Python SDK for Foritech Secure System.
Project description
Foritech SDK
Локален README за Python пакета. За пълна документация виж ../README.md.
Foritech SDK
Python SDK for Foritech Secure System.
Foritech SDK (Python)
Лек Python SDK за пост-квантова криптография (Kyber768/ML-KEM) и базови операции за ключове и файлово шифриране. Работи самостоятелно (Python) и/или чрез Docker-базирания CLI wrapper.
PyPI пакет: foritech-sdk • Лиценз: MIT • Поддържани Python: 3.11, 3.12, 3.13
Quickstart (60 секунди)
# 1) Инсталиране
pip install -U foritech-sdk
# 2) Минимален пример (encrypt/decrypt)
python - << 'PY'
from foritech import crypto # пример: модулът ви може да е foritech.crypto
data = b"hello post-quantum world"
aad = b"example-aad"
ct = crypto.encrypt(data, aad=aad) # връща {ciphertext, key/nonce/...} или bytes според API
pt = crypto.decrypt(ct, aad=aad)
assert pt == data
print("OK: encrypt/decrypt")
PY
# Foritech CLI Wrapper A — Implementation Pack
This package provides everything you asked for to implement Variant A (Docker-based CLI wrapper), plus the sync note for Variant B. Copy/paste files as indicated.
---
## 0) File tree (new/updated)
repo-root/ ├─ sdk/ │ ├─ pyproject.toml # + console_scripts entry (update) │ └─ src/ │ └─ foritech_cli/ │ ├─ init.py │ └─ main.py # wrapper entrypoint (argparse) ├─ docs/ │ └─ CLI_WRAPPER_SYNC.md # note: how to keep A in sync with B ├─ examples/ │ ├─ 01_keygen.sh # example using wrapper A │ ├─ 02_encrypt_file.sh │ └─ 03_decrypt_file.sh ├─ sdk/tests/ │ └─ test_cli_wrapper_smoke.py # pytest: skipped if no docker ├─ .github/workflows/ │ └─ cli-wrapper-smoke.yml # CI smoke job (Ubuntu) └─ README.md # add short “CLI (Wrapper)” section (update)
> If your SDK code lives under a different subpackage root, adjust imports/paths accordingly.
---
## 1) sdk/src/foritech_cli/__init__.py
```python
__all__ = ["main"]
from .main import main # re-export for console_scripts hook
2) sdk/src/foritech_cli/main.py (Docker wrapper)
import argparse
import os
import shutil
import subprocess
import sys
from typing import List
# Pin your canonical image here. Replace the digest with your current published image digest.
# You can also read it from an env var (FORITECH_IMAGE) with this as default.
DEFAULT_IMAGE = os.environ.get(
"FORITECH_IMAGE",
"ghcr.io/foritech-secure-system/foritech:stable@sha256:YOUR_PINNED_DIGEST_HERE",
)
# Common Docker args. We run as current user where possible to avoid root-owned outputs on Linux.
# On macOS/Windows this just works; on Linux it avoids permission issues.
def _docker_base_args() -> List[str]:
args = [
"docker",
"run",
"--rm",
"-i",
]
# Mount current working directory into /work (read-write)
cwd = os.getcwd()
args += ["-v", f"{cwd}:/work"]
# Propagate UID/GID on Linux to avoid root-owned output files
if os.name == "posix":
try:
uid = os.getuid()
gid = os.getgid()
args += ["-u", f"{uid}:{gid}"]
except AttributeError:
pass
# Set working dir inside container
args += ["-w", "/work"]
# Pass through basic envs if set (helpful for non-interactive CI)
for env_name in ("TZ", "FORITECH_LOGLEVEL"):
if env_name in os.environ:
args += ["-e", f"{env_name}={os.environ[env_name]}"]
return args
def _ensure_docker_available() -> None:
if not shutil.which("docker"):
print("Error: Docker is not installed or not in PATH.", file=sys.stderr)
sys.exit(127)
def run_container(image: str, inner_args: List[str]) -> int:
"""Run Docker with the given image and inner CLI args. Return the exit code."""
cmd = _docker_base_args() + [image] + inner_args
try:
proc = subprocess.run(cmd, check=False)
return proc.returncode
except KeyboardInterrupt:
return 130
except Exception as e:
print(f"Runtime error: {e}", file=sys.stderr)
return 2
def main(argv: List[str] | None = None) -> int:
_ensure_docker_available()
parser = argparse.ArgumentParser(
prog="foritech",
description="Foritech CLI (Docker wrapper). This mirrors the real Python CLI (when available).",
)
parser.add_argument(
"--image",
default=DEFAULT_IMAGE,
help="Docker image to use (pinned digest recommended). Can also set FORITECH_IMAGE env.",
)
sub = parser.add_subparsers(dest="command", required=True)
# foritech keygen --alg Kyber768 --out key.bin (example)
p_keygen = sub.add_parser("keygen", help="Generate Kyber768 keypair or KEM material.")
p_keygen.add_argument("--alg", default="Kyber768", help="Algorithm (default: Kyber768)")
p_keygen.add_argument("--out", required=True, help="Output path for generated key material")
# foritech encrypt --in file --out file.enc --aad optional
p_encrypt = sub.add_parser("encrypt", help="Encrypt file with SDK defaults.")
p_encrypt.add_argument("--in", dest="in_path", required=True, help="Input file")
p_encrypt.add_argument("--out", dest="out_path", required=True, help="Output file")
p_encrypt.add_argument("--aad", dest="aad", default=None, help="Additional authenticated data (optional)")
# foritech decrypt --in file.enc --out file
p_decrypt = sub.add_parser("decrypt", help="Decrypt file with SDK defaults.")
p_decrypt.add_argument("--in", dest="in_path", required=True, help="Input file")
p_decrypt.add_argument("--out", dest="out_path", required=True, help="Output file")
p_decrypt.add_argument("--aad", dest="aad", default=None, help="Aad value if used on encrypt (optional)")
# passthrough: forward unknown commands to the Docker CLI inside (advanced usage)
p_raw = sub.add_parser("raw", help="Pass through arguments directly to container CLI.")
p_raw.add_argument("args", nargs=argparse.REMAINDER, help="Arguments passed as-is to container")
args = parser.parse_args(argv)
# Map subcommands to inner container CLI invocations.
# Replace the inner command below with the actual CLI inside your Docker image.
# Example assumes your container exposes `foritech-cli` with similar verbs.
inner_cmd = ["foritech-cli"]
if args.command == "keygen":
inner = inner_cmd + [
"keygen",
"--alg", args.alg,
"--out", args.out,
]
return run_container(args.image, inner)
if args.command == "encrypt":
inner = inner_cmd + [
"encrypt",
"--in", args.in_path,
"--out", args.out_path,
]
if args.aad:
inner += ["--aad", args.aad]
return run_container(args.image, inner)
if args.command == "decrypt":
inner = inner_cmd + [
"decrypt",
"--in", args.in_path,
"--out", args.out_path,
]
if args.aad:
inner += ["--aad", args.aad]
return run_container(args.image, inner)
if args.command == "raw":
# Pass everything after 'raw' directly
return run_container(args.image, inner_cmd + args.args)
# Should not reach here
parser.print_usage(sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())
Replace
foritech-cliininner_cmdwith the actual command available inside your Docker image. Keep verbs (keygen/encrypt/decrypt) identical to what Variant B will provide.
3) sdk/pyproject.toml (snippet to add console script)
[project.scripts]
foritech = "foritech_cli.main:main"
Place this under the
sdk/pyproject.toml[project.scripts]table. If a scripts table already exists, merge the entry.
4) docs/CLI_WRAPPER_SYNC.md (sync note A ↔ B)
# CLI Wrapper A ↔ Python CLI B: Sync Note
**Purpose**: Wrapper A mirrors the future real Python CLI (Variant B). Whenever B changes, update A accordingly.
**Checklist on every B change:**
1. **Subcommands & names** — keep identical verbs (`keygen`, `encrypt`, `decrypt`).
2. **Flags & defaults** — reflect new/changed flags; sync default values.
3. **I/O formats** — keep output format/paths consistent; update examples.
4. **Errors & exit codes** — map exceptions to the same process codes.
5. **Logging levels** — align `--quiet/--verbose` semantics.
6. **Version/help** — `--version`/`--help` text and epigraph must match.
7. **Docs/CI** — update README examples and smoke tests as needed.
5) README.md (add short Wrapper section)
## CLI (Wrapper A)
The `foritech` command is a thin Docker-based wrapper that mirrors the upcoming native Python CLI. Requirements: Docker. You can override the image via `FORITECH_IMAGE` env or `--image` flag.
Quickstart:
```bash
foritech --help
foritech keygen --out mykey.bin
foritech encrypt --in secret.txt --out secret.txt.enc
foritech decrypt --in secret.txt.enc --out secret.txt
See docs/CLI_WRAPPER_SYNC.md for how this wrapper stays in sync with the native CLI.
---
## 6) examples (shell)
### examples/01_keygen.sh
```bash
#!/usr/bin/env bash
set -euo pipefail
foritech keygen --out mykey.bin
examples/02_encrypt_file.sh
#!/usr/bin/env bash
set -euo pipefail
: "${INPUT:=secret.txt}"
: "${OUTPUT:=secret.txt.enc}"
foritech encrypt --in "$INPUT" --out "$OUTPUT"
examples/03_decrypt_file.sh
#!/usr/bin/env bash
set -euo pipefail
: "${INPUT:=secret.txt.enc}"
: "${OUTPUT:=secret.txt}"
foritech decrypt --in "$INPUT" --out "$OUTPUT"
Make scripts executable:
chmod +x examples/*.sh
7) sdk/tests/test_cli_wrapper_smoke.py
import os
import shutil
import subprocess
import sys
import pytest
pytestmark = pytest.mark.skipif(shutil.which("docker") is None, reason="docker not available")
def test_foritech_help():
proc = subprocess.run([sys.executable, "-m", "foritech_cli.main", "--help"], capture_output=True, text=True)
assert proc.returncode == 0
assert "Foritech CLI" in proc.stdout
def test_foritech_image_override_env(monkeypatch):
monkeypatch.setenv("FORITECH_IMAGE", "alpine:3.19")
# We don't actually run a command here to avoid needing the inner CLI
proc = subprocess.run([sys.executable, "-m", "foritech_cli.main", "--help"], capture_output=True, text=True)
assert proc.returncode == 0
This is a lightweight smoke test to ensure the module loads and help works. E2E invoking the container is optional here and better suited for a separate job.
8) .github/workflows/cli-wrapper-smoke.yml
name: CLI Wrapper Smoke
on:
push:
branches: [ main ]
pull_request:
jobs:
smoke:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install sdk (editable)
run: |
cd sdk
pip install -U pip
pip install -e .
- name: foritech --help should work
run: |
foritech --help
This verifies the wrapper installs and prints help on Ubuntu with Docker available in the runner environment.
9) Commit checklist
git add sdk/src/foritech_cli docs/CLI_WRAPPER_SYNC.md examples/ \
sdk/tests/test_cli_wrapper_smoke.py .github/workflows/cli-wrapper-smoke.yml
# Also update sdk/pyproject.toml and README.md
git add sdk/pyproject.toml README.md
git commit -m "feat(cli): add Docker-based wrapper (Variant A) with smoke tests and docs"
git push -u origin <your-branch>
10) Notes
- Replace
YOUR_PINNED_DIGEST_HEREwith the actual image digest you publish. - Update
inner_cmdto match the command exposed inside your container (foritech-cliis a placeholder). - Keep verb names identical to what Variant B will implement to ease transition.
Foritech SDK
Лек Python SDK за криптография и интеграция с Foritech Secure System.
Инсталация
pip install foritech-sdk
##Quickstart
from foritech import __version__
print("foritech-sdk:", __version__)
-(Пример) Шифриране на байтове с Data Encryption Key (DEK)
-Примерният API е минимален и стабилен; ако сменим имена – ще обновим README.
from foritech import errors
def encrypt_bytes(data: bytes, key: bytes) -> bytes:
# TODO: използвай реалния SDK API при готовност
if not key:
raise errors.EncryptError("Missing key")
return data[::-1] # demo only
def decrypt_bytes(ct: bytes, key: bytes) -> bytes:
if not key:
raise errors.DecryptError("Missing key")
return ct[::-1]
pt = b"hello"
key = b"\x00" * 32
ct = encrypt_bytes(pt, key)
rt = decrypt_bytes(ct, key)
assert rt == pt
##Полезни връзки
--Репо: https://github.com/foritech-secure-system/foritech-secure-system
--Issues: https://github.com/foritech-secure-system/foritech-secure-system/issues
##Лиценз
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file foritech_sdk-0.1.3.tar.gz.
File metadata
- Download URL: foritech_sdk-0.1.3.tar.gz
- Upload date:
- Size: 34.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1139cdb9bd549c3a086882a824a22e067fc3d502bd52bc82cfa34ac747d3944
|
|
| MD5 |
f2f8281803e74a4ed186ed453323c16b
|
|
| BLAKE2b-256 |
ed55ec6a283ae44c64c9e174d9000e157fb9e24c949b59cd596ff9e66a2ea3be
|
Provenance
The following attestation bundles were made for foritech_sdk-0.1.3.tar.gz:
Publisher:
pypi-release.yml on foritech-secure-system/foritech-secure-system
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
foritech_sdk-0.1.3.tar.gz -
Subject digest:
b1139cdb9bd549c3a086882a824a22e067fc3d502bd52bc82cfa34ac747d3944 - Sigstore transparency entry: 545524223
- Sigstore integration time:
-
Permalink:
foritech-secure-system/foritech-secure-system@2e17c44d8ca7370e02d882bfcc127094c30b0bfd -
Branch / Tag:
refs/tags/sdk-v0.1.3 - Owner: https://github.com/foritech-secure-system
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-release.yml@2e17c44d8ca7370e02d882bfcc127094c30b0bfd -
Trigger Event:
push
-
Statement type:
File details
Details for the file foritech_sdk-0.1.3-py3-none-any.whl.
File metadata
- Download URL: foritech_sdk-0.1.3-py3-none-any.whl
- Upload date:
- Size: 39.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de658fc0a7fc34fd57c082120f5e00d754ebf13f7b96c4ba893caaa6adea55f4
|
|
| MD5 |
da71491b5400ba7493b552c17a501764
|
|
| BLAKE2b-256 |
7cfa9f1705c43858c82be02ffec35c9a524e72bfcd9976bb698be6f84f002dd2
|
Provenance
The following attestation bundles were made for foritech_sdk-0.1.3-py3-none-any.whl:
Publisher:
pypi-release.yml on foritech-secure-system/foritech-secure-system
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
foritech_sdk-0.1.3-py3-none-any.whl -
Subject digest:
de658fc0a7fc34fd57c082120f5e00d754ebf13f7b96c4ba893caaa6adea55f4 - Sigstore transparency entry: 545524228
- Sigstore integration time:
-
Permalink:
foritech-secure-system/foritech-secure-system@2e17c44d8ca7370e02d882bfcc127094c30b0bfd -
Branch / Tag:
refs/tags/sdk-v0.1.3 - Owner: https://github.com/foritech-secure-system
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-release.yml@2e17c44d8ca7370e02d882bfcc127094c30b0bfd -
Trigger Event:
push
-
Statement type: