Install & Compatibility
Where this runs
tested against v0.54.5 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.915 runs
installs and imports cleanly · install 0.0s · import 1.343s · 80.1MB
glibcpy 3.10–3.915 runs
installs and imports cleanly · install 7.2s · import 1.241s · 79MB
80MB installed
● package 80MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Tap
✓ from singer_sdk import Tap
Base class for all data extractors.
Stream
✓ from singer_sdk import Stream
Generic base class for tap streams.
RESTStream
✓ from singer_sdk.streams import RESTStream
Base class for REST API-based streams.
th (typing helpers)
✓ import singer_sdk.typing as th
Recommended alias for working with JSON schema typing.
SQLTap, SQLStream, SQLSink, SQLConnector, SQLTarget
✓ from singer_sdk.sql import SQLTap, SQLStream, SQLSink, SQLConnector, SQLTarget
✗ from singer_sdk import SQLTap
As of v0.57, SQL classes are no longer directly exposed at the top-level `singer_sdk` module. They must be imported from `singer_sdk.sql`.
This quickstart demonstrates how to build a simple Singer tap that extracts data from a REST API. It defines a `RESTStream` for a 'users' endpoint and a `Tap` class to configure and discover this stream. The example uses environment variables for sensitive API credentials to ensure it can be run securely.
import os
from singer_sdk import Tap, Stream
from singer_sdk.streams import RESTStream
import singer_sdk.typing as th
class UsersStream(RESTStream):
"""Users stream."""
name = "users"
url_base = os.environ.get("API_URL", "https://api.example.com")
path = "/users"
primary_keys = ["id"]
records_jsonpath = "$.data[*]"
schema = th.PropertiesList(
th.Property("id", th.IntegerType),
th.Property("name", th.StringType),
th.Property("email", th.StringType),
).to_dict()
class MyTap(Tap):
"""My custom tap."""
name = "tap-myapi"
config_jsonschema = th.PropertiesList(
th.Property("api_url", th.StringType, required=True),
th.Property("api_key", th.StringType, required=True, secret=True),
).to_dict()
def discover_streams(self):
return [UsersStream(self)]
# To run the tap (e.g., discover catalog or sync data):
# python -m your_tap_module --config config.json --discover > catalog.json
# python -m your_tap_module --config config.json --catalog catalog.json --state state.json > state_new.json
if __name__ == "__main__":
MyTap.cli()
singer --version
Debug
Known issues
breakingSQL-related classes (e.g., `SQLTap`, `SQLStream`, `SQLSink`, `SQLConnector`, `SQLTarget`) will be moved from top-level `singer_sdk` imports to `singer_sdk.sql`.fixUpdate your imports from `from singer_sdk import SQLTap` to `from singer_sdk.sql import SQLTap`.
affects: v0.57+
breakingThe functions `singer_sdk.testing.get_standard_tap_tests` and `singer_sdk.testing.get_standard_target_tests` will be removed. They are replaced by `singer_sdk.testing.get_tap_test_class` and `singer_sdk.testing.get_target_test_class` to generate richer test suites.fixMigrate your testing setup to use the new `get_tap_test_class` and `get_target_test_class` functions.
affects: v1.0+
breakingThe `PyJWT` and `cryptography` libraries for JWT authentication, and `SQLAlchemy` for SQL connectors, will no longer be installed by default. They will become optional extra dependencies.fixIf using `OAuthJWTAuthenticator`, install with `pip install singer-sdk[jwt]`. If using SQL-based taps/targets, install with `pip install singer-sdk[sql]` or explicitly install `SQLAlchemy`.
affects: v1.0+
deprecatedThe `Stream.reset_state_progress_marker` method is deprecated and its logic was never used at the stream level.fixRemove calls to `Stream.reset_state_progress_marker`. Review the SDK documentation for alternative state management patterns if needed.
affects: v0.53.3 - v0.54 (planned removal)
gotchaPrior to v0.53.6, specific interactions with the `simpleeval` dependency could lead to issues when using `json` within stream map expressions.fixUpgrade `singer-sdk` to v0.53.6 or newer. Ensure your `simpleeval` version is compatible if you manually manage it. Review usage of `json` in stream map expressions for compatibility.
affects: <0.53.6
gotchaThe SDK previously crashed with `SyntaxError: Unexpected end of JSON input` if an API returned an empty body with a `200` status code but without a `Content-Length: 0` header or a `204` status code.fixUpgrade to a newer version of `singer-sdk` (e.g., v0.53.5 or later) to benefit from improved JSON parsing error handling and graceful empty response management.
affects: <~0.53.5
gotchaWhen using stream map expressions, `NameNotDefined` errors (e.g., `'datetime' is not defined for expression 'datetime.datetime.now()'`) can occur if the `simpleeval` context does not have the necessary built-ins or if the SDK version is too old for specific functions.fixEnsure your SDK version is up-to-date. If encountering custom functions, verify the tap explicitly adds them to the `simpleeval` context. For common functions like `datetime`, ensure your SDK version supports them or consider more explicit imports within the expression if allowed by the tap's `simpleeval` configuration (though this is less common).
affects: All versions (if `simpleeval` context is not aligned with tap requirements or SDK is old)
Upgrade
Version history
0.54.5latest on PyPI · released Jun 16, 2026
Audit
Dependencies
No dependency data recorded yet.