datamasque.client package

Subpackages

Submodules

datamasque.client.base module

class datamasque.client.base.BaseClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: object

Shared state and HTTP plumbing for every feature client mixin.

Holds the connection config, cached auth token, and the core make_request dispatcher used by all per-feature mixins that compose DataMasqueClient.

authenticate() None[source]

Authenticate against the DataMasque server and cache the resulting token.

Called implicitly by make_request on the first request and on a 401 response, so you generally do not need to call this yourself.

When the client was constructed with a token_source callable, the callable is invoked instead of POSTing to the login endpoint.

base_url: str
healthcheck() None[source]

Pings the server’s unauthenticated healthcheck endpoint.

Returns without error when the server is up and ready to accept requests.

make_request(method: str, path: str, *, data: dict | None = None, params: dict | None = None, files: list[UploadFile] | None = None, requires_authorization: bool = True, require_status_check: bool = True) Response[source]

Sends an HTTP request to the DataMasque server and returns the Response.

When requires_authorization is true (the default), the current auth token is sent in the request headers, and a 401 response triggers one re-auth-and-retry.

Parameters:
  • method – HTTP method (e.g. "GET", "POST").

  • path – URL path such as /api/license/. Must include a trailing slash.

  • data – Request body. Serialised as JSON for normal requests, and as multipart form data when files is also provided.

  • params – Query string parameters, merged into the URL as ?key=value&....

  • files – Multipart form uploads; when set, the request is sent as multipart/form-data and data is sent alongside as form fields.

  • requires_authorization – When true (the default), the current auth token is attached and a 401 triggers one re-auth-and-retry.

  • require_status_check – When true (the default), a non-2xx response raises one of the exceptions below; when false, the Response is returned regardless of status so the caller can inspect it directly.

Raises:
  • DataMasqueApiError – When require_status_check is true (the default) and the response is non-2xx. The response object is available on the .response attribute of the exception.

  • DataMasqueNotReadyError – When require_status_check is true and the response is 502. 502 typically indicates the server is still starting up.

  • DataMasqueTransportError – When the request fails before any response is received (connection refused, timeout, DNS failure, SSL handshake failure, etc.).

password: str | None
token: str = ''
token_source: Callable[[], str] | None
username: str
verify_ssl: bool
class datamasque.client.base.UploadFile(field_name: str, filename: str, content: BufferedIOBase, content_type: str | None = None)[source]

Bases: object

Represents a file to upload in a multipart form request.

content: BufferedIOBase
content_type: str | None = None
field_name: str
filename: str
datamasque.client.base.read_file_or_content(file_or_content: str | bytes | TextIOBase | BufferedIOBase | Path, fallback_file_name: str) tuple[str, BufferedIOBase][source]

Takes either a filename (str), file path (Path), or some file content.

Where content is provided, the filename is given by fallback_file_name. Returns a tuple of the filename and a BytesIO containing the file content.

datamasque.client.base.suppress_insecure_warning_if_needed(verify_ssl: bool) Iterator[None][source]

Scope-limited suppression of InsecureRequestWarning when TLS verification is disabled.

datamasque.client.connections module

class datamasque.client.connections.ConnectionClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

Connection-related API methods. Mixed into DataMasqueClient.

create_or_update_connection(connection_config: ConnectionConfig) ConnectionConfig[source]

Creates or updates the connection in DM, and sets the id field on the given connection_config.

delete_connection_by_id_if_exists(connection_id: ConnectionId) None[source]

Deletes the connection with the given ID. No-op if the connection does not exist.

delete_connection_by_name_if_exists(connection_name: str) None[source]

Deletes the connection with the given name. No-op if the connection does not exist.

list_connections() list[ConnectionConfig][source]

Lists all configured connections.

Note that database passwords and connection strings are returned encrypted over the API and so are None on the returned ConnectionConfig objects.

datamasque.client.discovery module

class datamasque.client.discovery.DiscoveryClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

Schema-discovery and ruleset-generation API methods. Mixed into DataMasqueClient.

generate_file_ruleset(generation_request: FileRulesetGenerationRequest) str[source]

Generates file-masking ruleset YAML from the most recent file-data-discovery run on the given connection.

generation_request is a FileRulesetGenerationRequest.

generate_ruleset(generation_request: RulesetGenerationRequest) str[source]

Generates database-masking ruleset YAML from the most recent discovery run on the given connection.

generation_request is a RulesetGenerationRequest.

get_async_ruleset_generation_task_status(connection_id: ConnectionId) AsyncRulesetGenerationTaskStatus[source]

Queries the status of an async ruleset generation task.

get_file_data_discovery_report(run_id: RunId) list[FileDiscoveryResult][source]

Returns the file-data-discovery results for the specified run.

get_generated_rulesets(connection_id: ConnectionId) list[Ruleset][source]

Return the Ruleset objects produced by a previously-started async ruleset generation.

Use for all three async-RG flows:

Raises AsyncRulesetGenerationInProgressError if the task hasn’t finished yet, and DataMasqueException if it failed.

Note that the ruleset(s) have autogenerated names, which you may want to customize before uploading.

get_schema_discovery_page(run_id: RunId, *, limit: int = 50, offset: int = 0) SchemaDiscoveryPage[source]

Returns a single page of schema discovery results including table_metadata.

Use this when you need the table-constraint metadata alongside the results.

iter_schema_discovery_results(run_id: RunId) Iterator[SchemaDiscoveryResult][source]

Lazily iterate all schema discovery results for a run via the paginated v2 endpoint.

list_schema_discovery_results(run_id: RunId) list[SchemaDiscoveryResult][source]

Returns all schema discovery results for a run.

start_async_ruleset_generation(connection_id: ConnectionId, selected_data: SelectedColumns | SelectedFileData) None[source]

Starts async ruleset generation using the most recent discovery results on the given connection.

If the connection is a database connection, selected_data should be of type SelectedColumns. If the connection is a file connection, selected_data should be of type SelectedFileData.

Generation runs asynchronously on the server. Poll get_async_ruleset_generation_task_status until it returns AsyncRulesetGenerationTaskStatus.finished, then call get_generated_rulesets to retrieve the resulting Ruleset.

start_async_ruleset_generation_from_csv(connection_id: ConnectionId, csv_content: str | bytes | TextIOBase | BufferedIOBase, target_size_bytes: int | None = None) None[source]

Generate ruleset(s) from the schema discovery CSV file obtained from get_db_discovery_result_report().

target_size_bytes is an optional integer specifying the approximate size in bytes of each generated ruleset.

csv_content can be: - A string (e.g. from get_db_discovery_result_report()) - Bytes - A text file handle (e.g. open(path)) - A binary file handle (e.g. open(path, 'rb'))

Generation runs asynchronously on the server. Poll get_async_ruleset_generation_task_status until it returns AsyncRulesetGenerationTaskStatus.finished, then call get_generated_rulesets to retrieve the resulting Ruleset objects.

start_schema_discovery_run(discovery_config: SchemaDiscoveryRequest) RunId[source]

Starts a schema discovery run with the given configuration.

Parameters:

discovery_config – A SchemaDiscoveryRequest with connection ID and optional settings.

Returns:

The ID of the started discovery run

Return type:

RunId

Raises:

FailedToStartError – If run fails to start

datamasque.client.dmclient module

class datamasque.client.dmclient.DataMasqueClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: LicenseClient, ConnectionClient, RulesetClient, RulesetLibraryClient, FileClient, RunClient, DiscoveryClient, UserClient, SettingsClient

Client for a DataMasque server instance.

Example usage:

from datamasque.client import DataMasqueClient
from datamasque.client.models.dm_instance import DataMasqueInstanceConfig

config = DataMasqueInstanceConfig(
    base_url="https://datamasque.example.com",
    username="api_user",
    password="api_password",
)
client = DataMasqueClient(config)
client.authenticate()

for connection in client.list_connections():
    print(connection.name)

Authentication is performed on the first request if authenticate() is not called explicitly, and is automatically retried once on a 401 response.

class datamasque.client.dmclient.UploadFile(field_name: str, filename: str, content: BufferedIOBase, content_type: str | None = None)[source]

Bases: object

Represents a file to upload in a multipart form request.

content: BufferedIOBase
content_type: str | None = None
field_name: str
filename: str

datamasque.client.exceptions module

exception datamasque.client.exceptions.AsyncRulesetGenerationInProgressError[source]

Bases: DataMasqueException

Raised when attempting to retrieve results from a ruleset generation request that has not yet completed.

exception datamasque.client.exceptions.DataMasqueApiError(message: str, *, response: Response)[source]

Bases: DataMasqueException

Raised when the DataMasque server responds to a request with a non-2xx status code.

The triggering Response is always available on the .response attribute, so callers can inspect the status code, headers, and body for richer error handling.

502 Bad Gateway responses are raised as DataMasqueNotReadyError instead.

exception datamasque.client.exceptions.DataMasqueException[source]

Bases: Exception

Generic exception base class.

exception datamasque.client.exceptions.DataMasqueIfmError[source]

Bases: DataMasqueException

Generic base exception for IFM (in-flight masking) client errors.

exception datamasque.client.exceptions.DataMasqueNotReadyError[source]

Bases: DataMasqueException

Raised when the DataMasque server is not healthy, normally because it is still starting up.

exception datamasque.client.exceptions.DataMasqueTransportError[source]

Bases: DataMasqueException

Raised when a request to the DataMasque server fails before any response is received.

Covers connection refused, timeout, DNS failure, SSL handshake failure, and similar transport-layer errors. The originating requests exception is chained via __cause__.

exception datamasque.client.exceptions.DataMasqueUserError[source]

Bases: DataMasqueException

Raised when error occurs during user creation or configuration.

exception datamasque.client.exceptions.FailedToStartError(message: str, *, response: Response)[source]

Bases: DataMasqueApiError

Raised when start_masking_run fails to create the run.

Inherits .response from DataMasqueApiError, so callers can read the server’s status code and error body directly.

exception datamasque.client.exceptions.IfmAuthError[source]

Bases: DataMasqueIfmError

Raised when the IFM client cannot obtain or refresh a JWT (e.g. invalid credentials, missing scope).

exception datamasque.client.exceptions.InvalidLibraryError(message: str, *, response: Response)[source]

Bases: FailedToStartError

Specific error for when runs fail to start due to having an invalid ruleset library.

exception datamasque.client.exceptions.InvalidRulesetError(message: str, *, response: Response)[source]

Bases: FailedToStartError

Specific error for when runs fail to start due to having an invalid ruleset.

exception datamasque.client.exceptions.RunNotCancellableError[source]

Bases: DataMasqueUserError

Raised when cancel_run is called against a run that is no longer eligible for cancellation.

Typically this happens when the run is already finished, failed, or in the cancelling state itself.

datamasque.client.files module

class datamasque.client.files.FileClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

File-upload API methods. Mixed into DataMasqueClient.

delete_file_if_exists(file: DataMasqueFile) None[source]

Deletes a file. No-op if the file does not exist.

file must be an instance of a concrete subclass of DataMasqueFile. The file must have its ID set.

get_file_of_type_by_name(file_type: Type[FileTypeT], name: str) FileTypeT | None[source]

Looks for a file of the given type (a concrete subclass of DataMasqueFile) with the given name.

Returns it if found, otherwise None.

list_files_of_type(file_type: Type[FileTypeT]) list[FileTypeT][source]

Returns all files of the given type (a concrete subclass of DataMasqueFile).

upload_file(file_type: Type[FileTypeT], file_name: str, file_path_or_content: str | bytes | Path) FileTypeT[source]

Uploads a file of the given type to the DataMasque server.

file_type must be a concrete subclass of DataMasqueFile (SeedFile, OracleWalletFile, SslZipFile, SnowflakeKeyFile). file_path_or_content may be a path (as str or Path), raw bytes, or a file-like object.

upload_file_if_not_exists(file_type: Type[FileTypeT], file_path: str | Path) FileTypeT | None[source]

Upload a file only if one with the same name doesn’t already exist.

Parameters:
  • file_type – A concrete subclass of DataMasqueFile (e.g., SeedFile, OracleWalletFile).

  • file_path – Path to the file to upload.

Returns:

The uploaded file object if a new file was uploaded, or None if a file with the same name already exists.

datamasque.client.ifm module

Client for the DataMasque IFM (in-flight masking) HTTP API.

DataMasqueIfmClient mirrors the public IFM endpoints in a typed Python interface. Authentication is JWT-based: the access token is obtained from the admin server’s /api/auth/jwt/login/ endpoint and refreshed via /api/auth/jwt/refresh/ on a 401. Users may also supply a token_source callable in the connection config to bypass admin-server login entirely.

class datamasque.client.ifm.DataMasqueIfmClient(connection_config: DataMasqueIfmInstanceConfig)[source]

Bases: object

Client for a DataMasque IFM service.

Example usage:

from datamasque.client import DataMasqueIfmClient, DataMasqueIfmInstanceConfig

config = DataMasqueIfmInstanceConfig(
    admin_server_base_url="https://datamasque.example.com",
    ifm_base_url="https://datamasque.example.com/ifm",
    username="ifm_user",
    password="ifm_password",
)
client = DataMasqueIfmClient(config)

for plan in client.list_ruleset_plans():
    print(plan.name)

Authentication happens transparently on the first request, with automatic token refresh on expiry.

access_token: str = ''
admin_server_base_url: str
authenticate() None[source]

Obtain an access (and refresh) token from the admin server, or via token_source.

create_ruleset_plan(plan: RulesetPlanCreateRequest) RulesetPlan[source]

POST /ruleset-plans/ — create a new plan; returns the persisted view including its URL.

delete_ruleset_plan(plan_name: str) None[source]

DELETE /ruleset-plans/{plan_name}/ — no-op on the client side; raises on non-2xx server response.

get_ruleset_plan(plan_name: str) RulesetPlan[source]

GET /ruleset-plans/{plan_name}/ — fetch one plan including its ruleset YAML.

ifm_base_url: str
iter_ruleset_plans() Iterator[RulesetPlan][source]

Lazily iterate all ruleset plans via the paginated IFM endpoint.

list_ruleset_plans() list[RulesetPlan][source]

GET /ruleset-plans/ — list every ruleset plan visible to the current JWT.

mask(plan_name: str, request: IfmMaskRequest) IfmMaskResult[source]

POST /ruleset-plans/{plan_name}/mask/ — execute the named ruleset plan against request.data.

Returns an IfmMaskResult with success=True when the server returns 2xx (data carries the masked records), or success=False when the server returns a soft failure (HTTP 400 with the full mask-result shape — data omitted, logs populated). Network, auth, and other hard errors still raise DataMasqueApiError / IfmAuthError / DataMasqueNotReadyError.

password: str | None
patch_ruleset_plan(plan_name: str, plan: RulesetPlanPartialUpdateRequest) RulesetPlan[source]

PATCH /ruleset-plans/{plan_name}/ — partial update; only fields set on plan are sent.

refresh_token: str = ''
token_source: Callable[[], str] | None
update_ruleset_plan(plan_name: str, plan: RulesetPlanUpdateRequest) RulesetPlan[source]

PUT /ruleset-plans/{plan_name}/ — full replace of an existing plan.

username: str
verify_ssl: bool
verify_token() IfmTokenInfo[source]

GET /verify-token/ — returns the list of scopes granted to the current JWT.

datamasque.client.license module

class datamasque.client.license.LicenseClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

License management API methods. Mixed into DataMasqueClient.

get_current_license_info() LicenseInfo[source]

Returns information about the license currently installed on the server.

upload_license_file(license_file: str | bytes | TextIOBase | BufferedIOBase | Path) None[source]

Uploads a DataMasque license.

Specify the path to a license (.dmlicense) filename, or pass a StringIO or BytesIO containing the license content.

datamasque.client.ruleset_libraries module

class datamasque.client.ruleset_libraries.RulesetLibraryClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

Ruleset library CRUD API methods. Mixed into DataMasqueClient.

create_or_update_ruleset_library(library: RulesetLibrary) RulesetLibrary[source]

Creates the library if it doesn’t exist, or updates it if a library with the same name already exists.

Sets the library’s id property.

create_ruleset_library(library: RulesetLibrary) RulesetLibrary[source]

Creates a new ruleset library on the server.

Sets the library’s server-assigned fields (id, is_valid, created, modified) and returns the library.

delete_ruleset_library_by_id_if_exists(library_id: RulesetLibraryId, *, force: bool = False) None[source]

Deletes (archives) the ruleset library with the given ID.

No-op if the library does not exist.

If the library is imported by any rulesets, the server will return 409 Conflict unless force=True is passed.

delete_ruleset_library_by_name_if_exists(library_name: str, namespace: str = '', *, force: bool = False) None[source]

Deletes the ruleset library with the given name and namespace.

No-op if the library does not exist.

get_ruleset_library(library_id: RulesetLibraryId) RulesetLibrary[source]

Retrieves a single ruleset library by ID, including its YAML content.

get_ruleset_library_by_name(name: str, namespace: str = '') RulesetLibrary | None[source]

Looks for a ruleset library matching the given name and namespace (case-sensitive, exact match).

Returns it (with full YAML content) if found, otherwise None.

iter_ruleset_libraries() Iterator[RulesetLibrary][source]

Lazily iterate all ruleset libraries via paginated endpoint.

iter_rulesets_using_library(library_id: RulesetLibraryId) Iterator[Ruleset][source]

Lazily iterate non-archived rulesets that import the given library.

list_ruleset_libraries() list[RulesetLibrary][source]

Lists all ruleset libraries.

Note: The YAML content is not included in the list response for performance. Use get_ruleset_library to retrieve the full library with YAML content.

list_rulesets_using_library(library_id: RulesetLibraryId) list[Ruleset][source]

Lists non-archived rulesets that import the given library.

Note: The YAML content is not included in the response for performance. Each returned Ruleset will have an empty string for yaml.

update_ruleset_library(library: RulesetLibrary) RulesetLibrary[source]

Performs a full update of the ruleset library.

The library must have its id set (i.e., it must have been previously created or retrieved from the server).

validate_ruleset_library(library_id: RulesetLibraryId) RulesetLibrary[source]

Triggers re-validation of the ruleset library by performing a no-op update.

Returns the updated library with the new validation status.

datamasque.client.rulesets module

class datamasque.client.rulesets.RulesetClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

Ruleset CRUD API methods. Mixed into DataMasqueClient.

create_or_update_ruleset(ruleset: Ruleset) Ruleset[source]

Creates or updates a ruleset.

Populates the given ruleset’s id and is_valid fields from the server response, and returns the same ruleset instance for convenience.

delete_ruleset_by_id_if_exists(ruleset_id: RulesetId) None[source]

Deletes the ruleset with the given ID. No-op if the ruleset does not exist.

delete_ruleset_by_name_if_exists(ruleset_name: str) None[source]

Deletes the ruleset with the given name. No-op if the ruleset does not exist.

list_rulesets() list[Ruleset][source]

Returns all rulesets configured on the server.

datamasque.client.runs module

class datamasque.client.runs.RunClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

Masking-run and run-report API methods. Mixed into DataMasqueClient.

cancel_run(run_id: RunId) RunInfo[source]

Requests cancellation of the specified run and returns the updated run record.

On success the run transitions to the cancelling status; callers can poll get_run_info to observe the final cancelled status.

Parameters:

run_id – The ID of the run to cancel.

Returns:

The updated RunInfo for the run, with status set to cancelling.

Raises:
get_db_discovery_result_report(run_id: RunId, include_selection_column: bool = True) str[source]

Returns the database-discovery result report for the specified run as CSV.

When include_selection_column is true (the default), the CSV includes a selected column suitable for feeding back into ruleset generation.

get_run_info(run_id: RunId) RunInfo[source]

Returns the full run record for the specified run ID.

get_run_log(run_id: RunId) str[source]

Returns the full log output of the specified run.

get_run_report(run_id: RunId) str[source]

Retrieves the run report for the specified run.

Parameters:

run_id – The ID of the run

Returns:

The run report content

Return type:

str

get_sdd_report(run_id: RunId) str[source]

Returns the sensitive-data-discovery report generated by the specified run.

get_unfinished_runs() dict[str, UnfinishedRun][source]

Queries the DM instance for unfinished runs, and returns them organised by connection name.

start_masking_run(run_info: MaskingRunRequest) RunId[source]

Starts a masking run with the given configuration and returns its run ID.

Parameters:

run_info – A MaskingRunRequest describing the run configuration.

Raises:

datamasque.client.settings module

class datamasque.client.settings.SettingsClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

Server-wide settings, log retrieval, and admin-install bootstrap. Mixed into DataMasqueClient.

admin_install(email: str, username: str = 'admin', password: str | None = None, allowed_hosts: list[str] | None = None) None[source]

Performs the first-time admin-install bootstrap on a fresh DataMasque server.

Creates the initial admin account and configures the server’s allowed-hosts list. This endpoint is unauthenticated and can only be called once per server; subsequent calls will fail.

If password is not given, the client’s configured password is used. If allowed_hosts is not given, it defaults to the following list:

  • localhost

  • 127.0.0.1

  • the client’s configured hostname (from base_url).

retrieve_application_logs(output_path: Path) None[source]

Downloads the DataMasque application logs archive to output_path.

set_locality(locality: str) None[source]

Sets the server-wide locality used for ruleset generation and Jinja2 interpolation of ruleset YAML.

datamasque.client.users module

class datamasque.client.users.UserClient(connection_config: DataMasqueInstanceConfig)[source]

Bases: BaseClient

User CRUD API methods. Mixed into DataMasqueClient.

create_or_update_user(user: User, new_password: str | None = None) User[source]

Creates or updates the user.

An update will be performed if user.id is set, otherwise a create. To also set the user’s password, put the old password in the user’s password field (for an existing user) and pass the new password in the new_password parameter. Returns the same User object but with the id and password fields populated.

delete_user_by_id_if_exists(user_id: UserId) None[source]

Deletes the user with the given ID. No-op if the user does not exist.

delete_user_by_username_if_exists(username: str) None[source]

Deletes the user with the given username. No-op if the user does not exist.

list_users() list[User][source]

Returns all active users configured on the server.

reset_password_for_user(user: User) str[source]

Resets the user’s password.

The temporary password is stored on the User object and also returned.