diff --git a/codegen/pkg/builder/builder.go b/codegen/pkg/builder/builder.go index 22eb40d..6d32534 100644 --- a/codegen/pkg/builder/builder.go +++ b/codegen/pkg/builder/builder.go @@ -100,6 +100,10 @@ func (b *Builder) Build() error { return err } + if err := b.writeAPIVersionFile(path.Join(b.cfg.Out, "_api_version.py")); err != nil { + return err + } + took := time.Since(b.start) slog.Info("sdk generated", slog.Duration("took", took)) diff --git a/codegen/pkg/builder/out.go b/codegen/pkg/builder/out.go index 03a646d..25f117a 100644 --- a/codegen/pkg/builder/out.go +++ b/codegen/pkg/builder/out.go @@ -272,6 +272,24 @@ func (b *Builder) writeClientFile(fname string, tags []string) error { return nil } +func (b *Builder) writeAPIVersionFile(fname string) error { + f, err := os.OpenFile(fname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(0o755)) + if err != nil { + return fmt.Errorf("create %q: %w", fname, err) + } + defer func() { + _ = f.Close() + }() + + if err := b.templates.ExecuteTemplate(f, "api_version.py.tmpl", map[string]any{ + "Version": b.spec.Info.Version, + }); err != nil { + return fmt.Errorf("generate api version: %w", err) + } + + return nil +} + func openGeneratedFile(filename string) (*os.File, error) { cwd, err := os.Getwd() if err != nil { diff --git a/codegen/templates/api_version.py.tmpl b/codegen/templates/api_version.py.tmpl new file mode 100644 index 0000000..70c2173 --- /dev/null +++ b/codegen/templates/api_version.py.tmpl @@ -0,0 +1,2 @@ +# Code generated by `py-sdk-gen`. DO NOT EDIT. +__api_version__ = "{{ .Version }}" diff --git a/codegen/templates/client.py.tmpl b/codegen/templates/client.py.tmpl index 6c7be57..0ee6702 100644 --- a/codegen/templates/client.py.tmpl +++ b/codegen/templates/client.py.tmpl @@ -3,7 +3,7 @@ import os import httpx import typing -from ._service import Resource, AsyncResource +from ._service import Resource, AsyncResource, runtime_headers {{- range .Resources }} from .{{ .Package }} import {{ .Name }}Resource, Async{{ .Name }}Resource {{- end }} @@ -25,6 +25,7 @@ class Sumup(Resource): headers={ "User-Agent": f"sumup-py/{self.version()}", "Authorization": f"Bearer {self.api_key}", + **runtime_headers(), }, )) @@ -51,6 +52,7 @@ class AsyncSumup(AsyncResource): headers={ "User-Agent": f"sumup-py/{self.version()}", "Authorization": f"Bearer {self.api_key}", + **runtime_headers(), }, )) diff --git a/sumup/_api_version.py b/sumup/_api_version.py new file mode 100644 index 0000000..9d20483 --- /dev/null +++ b/sumup/_api_version.py @@ -0,0 +1,2 @@ +# Code generated by `py-sdk-gen`. DO NOT EDIT. +__api_version__ = "1.0.0" diff --git a/sumup/_client.py b/sumup/_client.py index 821f669..fa27d33 100644 --- a/sumup/_client.py +++ b/sumup/_client.py @@ -3,7 +3,7 @@ import httpx import typing -from ._service import Resource, AsyncResource +from ._service import Resource, AsyncResource, runtime_headers from .checkouts import CheckoutsResource, AsyncCheckoutsResource from .customers import CustomersResource, AsyncCustomersResource from .members import MembersResource, AsyncMembersResource @@ -35,6 +35,7 @@ def __init__( headers={ "User-Agent": f"sumup-py/{self.version()}", "Authorization": f"Bearer {self.api_key}", + **runtime_headers(), }, ) ) @@ -127,6 +128,7 @@ def __init__( headers={ "User-Agent": f"sumup-py/{self.version()}", "Authorization": f"Bearer {self.api_key}", + **runtime_headers(), }, ) ) diff --git a/sumup/_service.py b/sumup/_service.py index 7e6003a..126a7a9 100644 --- a/sumup/_service.py +++ b/sumup/_service.py @@ -1,4 +1,9 @@ import httpx +import platform +import sys +from functools import lru_cache + +from ._api_version import __api_version__ from ._version import __version__ HeaderTypes = dict[str, str] @@ -10,6 +15,48 @@ def version(): return f"v{__version__}" +def runtime_headers() -> dict[str, str]: + return dict(_runtime_headers()) + + +@lru_cache(maxsize=1) +def _runtime_headers() -> tuple[tuple[str, str], ...]: + arch_raw = platform.machine() + arch = arch_raw.lower() if arch_raw else "" + arch_map = { + "x86_64": "x86_64", + "x64": "x86_64", + "amd64": "x86_64", + "x86": "x86", + "i386": "x86", + "i686": "x86", + "ia32": "x86", + "x32": "x86", + "aarch64": "arm64", + "arm64": "arm64", + "arm": "arm", + } + arch = arch_map.get(arch, "unknown") + + os_name = sys.platform + os_map = { + "win32": "windows", + "linux": "linux", + "darwin": "darwin", + } + os_name = os_map.get(os_name, os_name) + + return ( + ("X-Sumup-Api-Version", __api_version__), + ("X-Sumup-Lang", "python"), + ("X-Sumup-Package-Version", __version__), + ("X-Sumup-Os", os_name), + ("X-Sumup-Arch", arch), + ("X-Sumup-Runtime", "python"), + ("X-Sumup-Runtime-Version", platform.python_version()), + ) + + class Resource(BaseResource): _client: httpx.Client