Skip to content
synsema why?
← All cases
Case 3 · Measured on 2026-10-16 · Synsema 0.6.44 · same data, same model on both sides

What a dependency can do

Your ETL imports a helper module. What can that module do with your program's permissions?

14 vs 0

third-party packages in the same 29-line ETL

The same ETL: 14 packages and 169 MB of other people's code in Python, zero in Synsema.

Python ETL14Synsema ETL0
Third-party packages installed for the same ETLEach square is one package, direct or transitive. 169 MB, 2,156 .py files and 99 native binaries on the Python side.

The problem

Poisoned packages on npm and PyPI that steal tokens and CI secrets are now a monthly event.

In Python or Node, any imported module runs with every permission the process has. A small ETL pulls in a dozen packages nobody reads.

What we built

  • A real ETL, written twice in 29 lines: daily weather for five cities from Open-Meteo to Parquet plus a CSV summary. Both produce the same numbers.
  • Each version imports a helper module that stands for any dependency. It formats numbers and also reports what it could do: read .env, open a connection to an undeclared host.
  • Dependency count, size and known vulnerabilities (pip-audit) on the Python side; synsema code caps and synsema build on the Synsema side.

Results

Same ETL, side by side
PythonSynsema
Packages, direct and transitive140
Third-party code on disk169 MB · 2,156 .py files · 99 native binariesnone
Known vulnerabilities (pip-audit)3 advisories in requests, pyarrow, python-dotenvnothing to audit
The imported module can read .envyesno
The imported module can reach an undeclared hostyesno
Know what it touches before runningno, read all 14 packagesyes, code caps flags MISSING file.read(".env") and net("example.com")
Distributioninterpreter + venv + 14 packagesone 45.9 MB binary
Run time6.8 to 9.3 s (1.3 s just importing; cities fetched in sequence)1.4 s (cities fetched in parallel)

The code, side by side

The usual way
Python ETLrequests, pandas, pyarrow, tenacity, python-dotenv.
import datetime as dt, json, sys
import requests, pandas as pd
from tenacity import retry, stop_after_attempt, wait_exponential
from dotenv import load_dotenv
import helpers

load_dotenv()
CITIES = {"Buenos Aires": (-34.61, -58.38), "Santiago": (-33.45, -70.67), "Lima": (-12.05, -77.04), "Bogotá": (4.71, -74.07), "Madrid": (40.42, -3.70)}

@retry(stop=stop_after_attempt(4), wait=wait_exponential(min=1, max=10))
def fetch(lat, lon, start, end):
    r = requests.get("https://archive-api.open-meteo.com/v1/archive", params={"latitude": lat, "longitude": lon, "start_date": start,
                     "end_date": end, "daily": "temperature_2m_max,precipitation_sum", "timezone": "auto"}, timeout=30)
    r.raise_for_status()
    return r.json()["daily"]

end = dt.date(2026, 10, 10); start = end - dt.timedelta(days=29)
rows = []
for city, (lat, lon) in CITIES.items():
    d = fetch(lat, lon, start.isoformat(), end.isoformat())
    rows += [{"city": city, "date": f, "tmax": t, "rain": p} for f, t, p in zip(d["time"], d["temperature_2m_max"], d["precipitation_sum"])]
df = pd.DataFrame(rows)
df.to_parquet(sys.argv[1] + "/weather_python.parquet", index=False)
summary = df.groupby("city").agg(tmax_mean=("tmax", "mean"), rain_total=("rain", "sum")).reset_index()
summary["tmax_mean"] = summary["tmax_mean"].map(helpers.round1)
summary.to_csv(sys.argv[1] + "/summary_python.csv", index=False)
print(summary.to_string(index=False))
print("what the imported module can do:", json.dumps(helpers.capabilities(), ensure_ascii=False))
cases/03-supply-chain/python/etl.py · from line 2
Synsema
The same ETL in SynsemaTwo requires: one host and one output folder. Nothing else.
use "./helpers.syn" as helpers
require net("archive-api.open-meteo.com")
require file.write("./cases/03-supply-chain/results/*")

let CITIES be [{"c": "Buenos Aires", "lat": -34.61, "lon": -58.38}, {"c": "Santiago", "lat": -33.45, "lon": -70.67},
               {"c": "Lima", "lat": -12.05, "lon": -77.04}, {"c": "Bogotá", "lat": 4.71, "lon": -74.07}, {"c": "Madrid", "lat": 40.42, "lon": -3.70}]
let END be date("2026-10-10")
let START be END - duration(days = 29)

task fetch(x)
    let n be 0
    while n < 4
        let r be http_get("https://archive-api.open-meteo.com/v1/archive", {}, {"latitude": text(x.lat), "longitude": text(x.lon),
            "start_date": text(START), "end_date": text(END), "daily": "temperature_2m_max,precipitation_sum", "timezone": "auto"}, 30)
        when r.ok
            let d be (json of r).daily
            give apply((e) => {"city": x.c, "date": e.item, "tmax": d.temperature_2m_max[e.index], "rain": d.precipitation_sum[e.index]}, enumerate(d.time))
        set n to n + 1
    raise(`could not fetch {x.c}`)

let rows be flatten(parallel_map(fetch, CITIES, 5))
write_file("./cases/03-supply-chain/results/weather_synsema.parquet", parquet_write(rows))
let summary be apply((r) => merge(r, {"tmax_mean": helpers.round1(r.tmax_mean)}), summarize(rows, "city", {"tmax_mean": mean_of("tmax"), "rain_total": sum_of("rain")}))
write_file("./cases/03-supply-chain/results/summary_synsema.csv", csv_encode(summary))
each r in summary
    print(`{r.city}: {r.tmax_mean} °C, {round_to(r.rain_total, 1)} mm`)
print(`what the imported module can do: {helpers.capabilities()}`)
cases/03-supply-chain/synsema/etl.syn · from line 3

Why Synsema

  • There is no package manager and no third-party code. Modules are local files.
  • A module only gets the capabilities the entry file declared. If the ETL declares one host, no module can talk to another.
  • synsema code caps is a static review: it shows what each task needs and what is missing, before anything runs.

What it does not solve

  • The pip-audit advisories go away by upgrading, which is exactly the continuous upkeep Python asks for.
  • A local Synsema module inherits the program's capabilities. If the program declares too much, the module gets it too.
  • The run-time gap is mostly sequential versus parallel downloads, not the language.

Reproduce it

git clone https://github.com/synsema/why-synsema && cd why-synsema
# cases/03-supply-chain
synsema run       cases/03-supply-chain/synsema/etl.syn
synsema code caps cases/03-supply-chain/synsema/etl.syn
uv run --with-requirements cases/03-supply-chain/python/requirements.txt python cases/03-supply-chain/python/etl.py cases/03-supply-chain/results
uvx pip-audit -r cases/03-supply-chain/python/requirements.txt

github.com/synsema/why-synsema/tree/main/cases/03-supply-chain

Share