Pydmart
This is a Python Dmart client (v1.3.x) used to interact with a Dmart instance
Installation
Pydmart is distributed via PyPI:
pip install pydmart
Example
The DmartService class provides methods to interact with a Dmart instance. Below is a detailed explanation of each method available in the class.
- Initialize the service by providing the base URL of the Dmart instance:
service = DmartService("http://localhost:8282")
- Perform a login action using the provided shortname and password:
login = await service.login("dmart", "Test1234")
- Sign in with a device id and the second step. Mobile accounts must name a device
(dmart >= 1.7.2), and an admin or a new device gets
OTP_NEEDED(115) and a code:
from pydmart import DmartException, DmartErrorCode
service = DmartService("http://localhost:8282", device_id="phone-1") # sent as X-DeviceId
try:
await service.login("dmart", "Test1234")
except DmartException as e:
if e.error.code == DmartErrorCode.OTP_NEEDED:
await service.login("dmart", "Test1234", otp=input("code: "))
elif e.error.code == DmartErrorCode.USER_ISNT_VERIFIED:
... # the address isn't verified: offer a code login or a password reset
else:
raise
- Fetch the profile of the current user:
me = await service.get_profile()
- Create a new space:
action_request_record = ActionRequestRecord(
resource_type=ResourceType.space,
shortname="myspace_test",
subpath="/",
attributes={
"is_active": True
}
)
action_request = ActionRequest(
space_name="myspace_test",
request_type=RequestType.create,
records=[action_request_record]
)
space = await service.request(action_request)
- Remove a space:
action_request_record = ActionRequestRecord(
resource_type=ResourceType.space,
shortname="myspace_test",
subpath="/",
attributes={}
)
action_request = ActionRequest(
space_name="myspace_test",
request_type=RequestType.delete,
records=[action_request_record]
)
space = await service.request(action_request)
- Query the spaces:
query_request = QueryRequest(
type=QueryType.spaces,
space_name="management",
subpath="/",
search=""
)
query = await service.query(query_request)
- Query with a join (attach related entries from another subpath):
from pydmart import JoinQuery, JoinType
orders = QueryRequest(
type=QueryType.subpath,
space_name="shop",
subpath="orders",
search="",
retrieve_json_payload=True,
join=[
JoinQuery(
# left path is read from each order, right path from the joined records
join_on="payload.body.customer:shortname",
alias="customer", # results land under record.attributes["join"]["customer"]
type=JoinType.left, # left (default) | right | inner | outer
query=QueryRequest( # the right side: which entries to join against
type=QueryType.subpath,
space_name="shop",
subpath="customers",
search="",
retrieve_json_payload=True,
),
),
],
)
response = await service.query(orders)
for record in response.records:
matched = record.attributes.get("join", {}).get("customer", [])
# `matched` is the list of joined customer records for this order
APIs
-
DmartService(base_url: str, device_id: Optional[str] = None)Creates the client.device_id, when set, is sent as theX-DeviceIdheader on sign-in. -
login(shortname: str, password: Optional[str], otp: Optional[str] = None, device_id: Optional[str] = None) -> ApiResponsePerforms a login with the shortname and password. When dmart answersOTP_NEEDED(115), call it again with the same password anddevice_idplus theotp. Passpassword=Noneandotpfor a code login.USER_ISNT_VERIFIED(11) means the address isn't verified yet. -
login_by(credentials: dict, password: str) -> ApiResponsePerforms a login action using custom credentials (email,msisdn, and optionallyotp,device_id) and password. -
logout() -> ApiResponsePerforms a logout action. -
create_user(request: dict, shortname: Optional[str] = None) -> ActionResponseRegisters a user via/user/createwith{"attributes": {...}}. Open registration needsemail_otp/msisdn_otpcodes fromotp_request(OtpPurpose.register, ...)(dmart >= 1.7.10).shortnameis the chosen username, or"auto"(dmart >= 1.7.9). -
update_user(request: dict) -> ActionResponseUpdates an existing user with the provided request data. No longer accepts contact-change fields (email,new_email,email_otp,msisdn,new_msisdn,msisdn_otp) — useotp_requestwithpurpose="verify-contact"followed byconfirm_otpinstead. Changing the password needsold_password. -
check_existing(prop: str, value: str) -> ResponseEntryChecks if a user exists based on the provided property and value. -
otp_request(self, purpose: OtpPurpose, msisdn: Optional[str] = None, email: Optional[str] = None, shortname: Optional[str] = None, accept_language: Optional[str] = None)Requests an OTP (One Time Password) for the provided MSISDN, email, or shortname.purposeis required and must be one oflogin,reset,register,verify-contact(seeOtpPurpose). Usepurpose="login"in place of the oldotp_request_login, andpurpose="reset"in place of the oldpassword_reset_request. -
confirm_otp(self, otp: str, msisdn: Optional[str] = None, email: Optional[str] = None, password: Optional[str] = None, current_code: Optional[str] = None)Verifies a contact's OTP code (sent viaotp_request) using the given MSISDN or email. Changing an address needspassword, orcurrent_code(a code sent to the existing address) on an account without a password. -
password_reset_confirm(self, otp: str, password: str, shortname: Optional[str] = None, email: Optional[str] = None, msisdn: Optional[str] = None)Sets a new password with a code fromotp_request(OtpPurpose.reset, ...). Name the account with exactly one ofshortname,emailormsisdn. -
get_client_config() -> ApiResponseReadsGET /public/client-config(no sign-in): OTP length and timings, upload and query limits, and the password and username rules' hints, underattributes. -
validate_password(self, password: str)Validates the provided password against the Dmart password policy. -
get_profile() -> ProfileResponseGets the profile of the current user. Its permission map is deprecated by dmart in favour ofget_permissions(). -
get_permissions() -> Dict[str, Any]Gets the current user's permission map fromGET /user/permissions, keyed"space:subpath:resource_type", and caches it incurrent_user_permissions. A server without that route is answered from the profile. -
query(query: QueryRequest, scope: str = "managed") -> ApiResponsePerforms a query action with the provided query request and scope. Leavelimitunset to get the server's default page size.response.total_is_lower_boundis True when the server capped the count. -
csv(query: QueryRequest, preview: bool = False) -> str | ApiResponseExports the entries as CSV and returns the CSV text.preview=Truereturns anApiResponsedescribing what the file would hold instead. -
request(action: ActionRequest) -> ActionResponsePerforms a request action with the provided action request. Spaces are created and deleted here too, withresource_type=ResourceType.space. -
retrieve_entry(resource_type: ResourceType, space_name: str, subpath: str, shortname: str, retrieve_json_payload: bool = False, retrieve_attachments: bool = False, scope: str = "managed") -> ResponseEntryRetrieves an entry based on the provided parameters. -
upload_with_payload(space_name: str, subpath: str, shortname: str, resource_type: ResourceType, payload_file: Any, content_type: Optional[ContentType] = None, schema_shortname: Optional[str] = None) -> ApiResponseUploads a file with payload to the specified space. -
get_spaces() -> ApiResponseGets the list of spaces. -
get_children(space_name: str, subpath: str, limit: int = 20, offset: int = 0, restrict_types: Optional[List[ResourceType]] = None) -> ApiResponseGets the children of a specified space. -
get_attachment_url(resource_type: ResourceType, space_name: str, subpath: str, parent_shortname: str, shortname: str, ext: Optional[str] = None, scope: str = "managed") -> strGets the URL of an attachment. -
get_space_health(space_name: str, health_type: str = "soft") -> ApiResponseGets the health status of a specified space (soft,hardorall). Global admins only. -
get_attachment_content(resource_type: str, space_name: str, subpath: str, shortname: str, scope: str = "managed") -> Dict[str, Any]Gets the content of an attachment. -
get_payload(resource_type: str, space_name: str, subpath: str, shortname: str, ext: str = ".json", scope: str = "managed") -> Dict[str, Any]Gets the payload of a specified resource. -
get_payload_content(resource_type: str, space_name: str, subpath: str, shortname: str, ext: str = ".json", scope: str = "managed") -> Dict[str, Any]Gets the content of a payload. -
progress_ticket(space_name: str, subpath: str, shortname: str, action: str, resolution: Optional[str] = None, comment: Optional[str] = None) -> Dict[str, Any]Progresses a ticket with the provided parameters. -
submit(space_name: str, schema_shortname: str, subpath: str, record: Dict[str, Any]) -> Dict[str, Any]Submits a record to the specified space and schema. -
get_manifest() -> Dict[str, Any]Gets the manifest information. -
get_settings() -> Dict[str, Any]Gets the settings information.
Metadata
Release files for pydmart 2.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pydmart-2.7.0.tar.gz | 32.8 kB | Without provenance | Details for pydmart-2.7.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pydmart-2.7.0-py3-none-any.whl | Python 3 | none | any | Details for pydmart-2.7.0-py3-none-any.whl |
Total release size: 53.1 kB
Release files / pydmart-2.7.0.tar.gz
| Download URL | pydmart-2.7.0.tar.gz |
|---|---|
| Size | 32.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
90fa1e0d3b192ef7e53fde4cc72256955d6fa9264cb6370d173c5662276f82f7
|
|
BLAKE2b-256 checksum How to use checksums |
b70d94a1cab51be64ab42b9e95938a0580b254c751f0b2477fc4f54fe0eb8a21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.10
|
Release files / pydmart-2.7.0-py3-none-any.whl
| Download URL | pydmart-2.7.0-py3-none-any.whl |
|---|---|
| Size | 20.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
538e70411690cc9c6d9a81c3df2e8be5a3d46d9fc13f50aa613d78678687edf4
|
|
BLAKE2b-256 checksum How to use checksums |
0e2f5844ee79a2d84404bcfaf3ec236ef104809668a00dd50349bab782b3c3d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.10
|
Security for pydmart 2.7.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.