signedly 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. signedly/__init__.py +92 -0
  2. signedly/api/__init__.py +14 -0
  3. signedly/api/api_request_logs_api.py +686 -0
  4. signedly/api/authentication_api.py +603 -0
  5. signedly/api/bulk_sending_api.py +858 -0
  6. signedly/api/documents_api.py +2465 -0
  7. signedly/api/downloads_api.py +840 -0
  8. signedly/api/fields_api.py +2308 -0
  9. signedly/api/sending_api.py +890 -0
  10. signedly/api/signatories_api.py +1165 -0
  11. signedly/api/templates_api.py +1452 -0
  12. signedly/api/webhooks_api.py +2582 -0
  13. signedly/api_client.py +798 -0
  14. signedly/api_response.py +21 -0
  15. signedly/configuration.py +596 -0
  16. signedly/exceptions.py +200 -0
  17. signedly/helpers.py +89 -0
  18. signedly/models/__init__.py +66 -0
  19. signedly/models/create_bulk_send202_response.py +105 -0
  20. signedly/models/create_bulk_send_request.py +101 -0
  21. signedly/models/create_document_fields_request_inner.py +156 -0
  22. signedly/models/create_document_from_template200_response.py +101 -0
  23. signedly/models/create_document_from_template_request.py +115 -0
  24. signedly/models/create_document_from_template_request_recipients_inner.py +92 -0
  25. signedly/models/create_signatories_request.py +100 -0
  26. signedly/models/create_signatories_request_signatories_inner.py +92 -0
  27. signedly/models/create_signatory_request.py +94 -0
  28. signedly/models/create_template_fields_request_inner.py +156 -0
  29. signedly/models/create_webhook_endpoint_request.py +103 -0
  30. signedly/models/delete_field_request.py +88 -0
  31. signedly/models/document.py +159 -0
  32. signedly/models/document_page.py +113 -0
  33. signedly/models/document_status_page.py +113 -0
  34. signedly/models/document_status_row.py +90 -0
  35. signedly/models/fill_and_send_document_request.py +116 -0
  36. signedly/models/fill_and_send_document_request_elements_inner.py +96 -0
  37. signedly/models/get_access_token_request.py +90 -0
  38. signedly/models/get_audit_trail_link200_response.py +88 -0
  39. signedly/models/get_download_status200_response.py +90 -0
  40. signedly/models/list_bulk_send_columns200_response_inner.py +92 -0
  41. signedly/models/model_field.py +202 -0
  42. signedly/models/page.py +102 -0
  43. signedly/models/refresh_access_token200_response.py +99 -0
  44. signedly/models/refresh_access_token_request.py +88 -0
  45. signedly/models/request_count_page.py +113 -0
  46. signedly/models/request_hit.py +93 -0
  47. signedly/models/request_log.py +108 -0
  48. signedly/models/request_log_page.py +113 -0
  49. signedly/models/send_document200_response.py +88 -0
  50. signedly/models/send_document_by_link200_response.py +90 -0
  51. signedly/models/send_document_by_link_request.py +91 -0
  52. signedly/models/send_document_request.py +102 -0
  53. signedly/models/signatory.py +119 -0
  54. signedly/models/template.py +124 -0
  55. signedly/models/template_field.py +202 -0
  56. signedly/models/template_page.py +113 -0
  57. signedly/models/update_document_field_by_body_request.py +158 -0
  58. signedly/models/update_document_field_by_body_request_items_inner.py +92 -0
  59. signedly/models/update_webhook_endpoint_request.py +105 -0
  60. signedly/models/upload.py +110 -0
  61. signedly/models/upload_document_for_one_signer200_response.py +90 -0
  62. signedly/models/upload_document_for_one_signer_request.py +96 -0
  63. signedly/models/upload_document_request.py +101 -0
  64. signedly/models/webhook_delivery.py +140 -0
  65. signedly/models/webhook_delivery_page.py +113 -0
  66. signedly/models/webhook_endpoint.py +116 -0
  67. signedly/models/webhook_endpoint_with_secret.py +120 -0
  68. signedly/py.typed +0 -0
  69. signedly/rest.py +258 -0
  70. signedly-0.1.0.dist-info/LICENSE +21 -0
  71. signedly-0.1.0.dist-info/METADATA +18 -0
  72. signedly-0.1.0.dist-info/RECORD +74 -0
  73. signedly-0.1.0.dist-info/WHEEL +5 -0
  74. signedly-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,686 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ Signedly API
5
+
6
+ The Signedly REST API lets your system upload documents, add signatories and fields, send them for signing and download the signed result. Every path starts with `/ap1/`, and every request and response body is JSON unless an endpoint says otherwise (the uploads are `multipart/form-data`). ## Authentication 1. In the Signedly web app, open **Account & Settings → API** and generate a **client ID** and **client secret** for your organisation. 2. `POST /ap1/token/` with them. You get an `access_token` (valid **2 hours**) and a `refresh_token` (valid **7 days**). While both are still valid, calling `/ap1/token/` again returns the same pair. 3. Send the access token on every other call: `Authorization: Bearer <access_token>`. 4. When the access token expires, `POST /ap1/refreshtoken/` with the refresh token for a new access token. When the refresh token has expired too, call `/ap1/token/` again. `/ap1/token/` and `/ap1/refreshtoken/` allow 60 calls a minute per IP address; more answer 429. A missing, unknown or expired access token answers 403 (`\"Client not found\"` or `\"Access token expired\"`). The API acts for your **organisation's admin account**: documents you upload belong to it and appear in its Signedly web app, and you can reach only that account's documents, templates, signatories and fields. Another organisation's IDs answer 404, as if they didn't exist. ## Plans What the API allows depends on the Signedly plan of your **organisation's admin account** (Account & Settings → Account & Plan). The same rules apply to live and test keys. | What | Free | Personal Pro | Business Pro | Teams | |---|---|---|---|---| | Generate live and test keys (Account & Settings → API) | – | ✓ | ✓ | ✓ | | Every endpoint, `/ap1/token/` and `/ap1/refreshtoken/` included | – | ✓ | ✓ | ✓ | | `require_email_otp` on `POST /ap1/signatories/` and `POST /ap1/signatories/bulk/` | – | ✓ | ✓ | ✓ | | Bulk send: `GET /ap1/bulk-sends/columns/` and `POST /ap1/bulk-sends/` | – | – | – | ✓ | The API is part of the paid plans. On Free (or with no plan) every call answers 403 `\"... Your plan doesn't include API access.\"`, with live or test keys, also with a token or keys made earlier; they work again once the plan is paid. On a paid plan, a feature it doesn't include answers 400 with `\"Your plan doesn't include ...\"` and changes nothing, and `GET /ap1/bulk-sends/{id}/` still reports bulk sends already made. Live documents also need an API contract with Signedly. Without one, or with an unpaid API invoice, `POST /ap1/upload/` (except templates), `/ap1/upload_app/`, `/ap1/documents/fromtemplate/` and `/ap1/bulk-sends/` answer 402 with live keys. Test keys work without a contract (see Sandbox). ## Sending a document for signing 1. `POST /ap1/upload/` a PDF or DOCX (`type` 2). The document is prepared in the background: find it in `GET /ap1/documents/?name=<name>` (its `upload.id` is the upload's `id`), and wait until `GET /ap1/documents/{id}/pages/` lists its pages. 2. `POST /ap1/signatories/` (one) or `POST /ap1/signatories/bulk/` (several) to add the people who sign. 3. `POST /ap1/documents/fields/` to place the fields each signatory fills in. 4. Send it: - `POST /ap1/document/send/` emails every signatory a signing link (with ordered signing, only the first; each next one is emailed in turn), or - `POST /ap1/document/send_url/` sends no email and returns the first signatory's signing link, for you to show or send yourself. 5. Poll `GET /ap1/documents-status-list/` (or `GET /ap1/documents/`) until the status is 6 (Completed), then `GET /ap1/document/download-link/` for the signed PDF and `GET /ap1/document/download-audit-link/` for its audit trail. **From a template:** upload with `type` 4 and a `template_name` (or make the template in the web app), place its fields with `POST /ap1/templates/fields/`, then for each signing make a document with `POST /ap1/documents/fromtemplate/`, add its signatory, and send it. **One signer, one call:** `POST /ap1/upload_app/` uploads a PDF or DOCX for one signer and returns their signing link in `redirect_url`; the signer places their own signature. After signing they go to the `redirect_url` you sent, and the signed PDF and its audit trail are emailed to `final_email` (otherwise to your organisation's admin). ## Quick start with curl Each step uses an ID from the step before. `$API` is this server, e.g. `https://l0ads.signedly.com`. ```bash # 1. Token curl -X POST $API/ap1/token/ -H 'Content-Type: application/json' \\ -d '{\"client_id\": \"<client id>\", \"client_secret\": \"<client secret>\"}' TOKEN=<access_token from the answer> # 2. Upload a PDF (answers with the upload's id) curl -X POST $API/ap1/upload/ -H \"Authorization: Bearer $TOKEN\" \\ -F file=@nda.pdf -F name=nda-ann-lee -F type=2 # 3. Find the document, then wait until it has pages curl \"$API/ap1/documents/?name=nda-ann-lee\" -H \"Authorization: Bearer $TOKEN\" DOC=<results[0].id> curl $API/ap1/documents/$DOC/pages/ -H \"Authorization: Bearer $TOKEN\" PAGE=<[0].id> # 4. Add the signatory curl -X POST $API/ap1/signatories/ -H \"Authorization: Bearer $TOKEN\" \\ -H 'Content-Type: application/json' \\ -d '{\"document_id\": \"'$DOC'\", \"name\": \"Ann Lee\", \"email\": \"ann@example.com\"}' SIGNER=<id from the answer> # 5. Place her signature: 150 × 40 points, 72 points from the left, 640 from the top curl -X POST $API/ap1/documents/fields/ -H \"Authorization: Bearer $TOKEN\" \\ -H 'Content-Type: application/json' \\ -d '[{\"document_id\": \"'$DOC'\", \"signatory_id\": \"'$SIGNER'\", \"kind\": 2, \"label\": \"Signature\", \"placeholder\": \"Sign here\", \"page\": \"'$PAGE'\", \"page_number\": 0, \"x\": 72, \"y\": 640, \"width\": 150, \"height\": 40}]' # 6. Send it (Ann gets the signing email) curl -X POST $API/ap1/document/send/ -H \"Authorization: Bearer $TOKEN\" \\ -H 'Content-Type: application/json' \\ -d '{\"document_id\": \"'$DOC'\", \"subject\": \"Please sign the NDA\", \"message\": \"Hi Ann, please sign by Friday.\", \"expiry_date\": \"2026-12-31\"}' # 7. Poll until status is 6 (Completed), then get the signed PDF curl \"$API/ap1/documents-status-list/?document_ids=$DOC\" -H \"Authorization: Bearer $TOKEN\" curl \"$API/ap1/document/download-link/?id=$DOC\" -H \"Authorization: Bearer $TOKEN\" ``` ## Postman Import the whole API into Postman with **Import → Link** and `<this server>/swaggerap1/postman.json`. Set `client_id` and `client_secret` in the collection's **Variables**, run **Get an access token** (it saves the token for every other request), and set `document_id` when a request needs one. ## Webhooks Instead of polling, add an endpoint with `POST /ap1/webhooks/` (or in **Account & Settings → API**) and Signedly posts your organisation's document events to it: `document.sent`, `document.viewed`, `document.signed`, `document.approved`, `document.completed`, `document.rejected` and `document.expired` (all of them, or the `events` you choose). Each is a JSON `POST`: ```json {\"id\": \"5b7f…\", \"type\": \"document.signed\", \"created_at\": \"2026-10-27T09:12:00+00:00\", \"test\": false, \"data\": {\"document\": {\"id\": \"6f0c…\", \"name\": \"nda.pdf\", \"status\": 5}, \"recipient\": {\"id\": \"0b6e…\", \"email\": \"ann@example.com\", \"name\": \"Ann Lee\", \"role\": \"signer\"}}} ``` `recipient` is null for events no recipient caused (sent, completed, expired); `test` is true for documents made with your test keys. Fetch anything else, such as download links, with your access token: events never carry links. **Check every event is from Signedly.** The `Signedly-Signature` header is `t=<unix seconds>,v1=<signature>`, where the signature is the hex HMAC-SHA256 of `<t>.<raw body>` with the endpoint's secret. Refuse an event whose signature doesn't match or whose `t` is more than 5 minutes off: ```python import hashlib, hmac, time def is_from_signedly(secret, header, raw_body): parts = dict(item.split(\"=\", 1) for item in header.split(\",\")) signed = f\"{parts['t']}.{raw_body.decode()}\".encode() expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() fresh = abs(time.time() - int(parts[\"t\"])) <= 300 return fresh and hmac.compare_digest(parts[\"v1\"], expected) ``` **Answer 2xx within 10 seconds**, then do the work. Anything else is retried after 1 and 5 minutes, then 30 minutes and 2, 5 and 10 hours (7 tries in about 18 hours). `Signedly-Event-Id` is the same on every try of an event: use it to ignore repeats. After 20 events in a row fail for good, Signedly switches the endpoint off and emails your organisation's admin; switch it on again with `PUT /ap1/webhooks/{id}/` and `\"is_active\": true`. Each endpoint's deliveries and their last answers are at `GET /ap1/webhooks/{id}/deliveries/`, and any can be sent again. ## Sandbox Build and test against the API without paying for documents: in **Account & Settings → API**, generate your **test keys**, and get a token with them at `/ap1/token/` as usual. Everything works the same, except that what you upload or make from a template with a test token is a **test document** (`is_test` on its upload): - every page of its PDF and of its audit trail says **TEST – NOT LEGALLY BINDING**; - its emails are real, with `[TEST]` at the start of the subject; - it isn't billed or counted toward your plan; - your organisation can make 50 a calendar month (templates don't count); the next upload answers 429. ## Fields Positions and sizes are in **PDF points** (1/72 inch), measured from the **top-left corner** of the page as it is displayed (rotation applied). `page_number` counts pages from 0. A field must sit wholly on its page (1 point of tolerance); otherwise it is refused with 400. A field's page and signatory can't be changed later: delete the field and add it again. ## Status values **Document `status`:** 1 Draft · 2 Signees Added · 3 Prepared · 4 Sent · 5 In Progress · 6 Completed · 7 Rejected · 8 Archived · 9 Expired. Signatories, fields and sends are only accepted while a document is 1–3 (not yet sent). **Signatory `status`:** 1 Waiting · 2 Invited · 3 Signed · 4 Viewed · 5 Rejected. ## Lists `GET /ap1/documents/`, `/ap1/documents-status-list/`, `/ap1/templates/`, `/ap1/logs/` and `/ap1/logs/hits/` are paged: pass `limit` (default 10) and `offset`, and read `count`, `next`, `previous` and `results` from the response. ## Errors | Status | Meaning | |---|---| | 400 | The request was refused, also when your plan doesn't include it (see Plans); the body says why (`{\"error\": \"...\"}`, or the name of each bad field with its messages). Nothing was changed. | | 403 | The access token is missing, unknown or expired; the client ID and secret or the refresh token were refused; the organisation's plan has no API access (Free, see Plans); or an `expiry_date` isn't in the future (`\"Invalid Date Entered\"`). | | 402 | No API contract, or an unpaid API invoice: live documents are refused (test keys keep working). | | 404 | The document, template, signatory or field doesn't exist or isn't yours. | | 429 | Too many token requests (wait a minute), or this month's 50 test documents are used. | | 5xx | Our side failed; retry later. | A send that times out may still have worked: check the document's status before sending again (a second send of a sent document answers 400). Download, view and audit links are valid for about 7 days; ask for a new one whenever you need it.
7
+
8
+ The version of the OpenAPI document: v1
9
+ Contact: info@signedly.com
10
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
11
+
12
+ Do not edit the class manually.
13
+ """ # noqa: E501
14
+
15
+ import warnings
16
+ from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
17
+ from typing import Any, Dict, List, Optional, Tuple, Union
18
+ from typing_extensions import Annotated
19
+
20
+ from pydantic import Field, StrictInt, StrictStr, field_validator
21
+ from typing import Optional
22
+ from typing_extensions import Annotated
23
+ from signedly.models.request_count_page import RequestCountPage
24
+ from signedly.models.request_log_page import RequestLogPage
25
+
26
+ from signedly.api_client import ApiClient, RequestSerialized
27
+ from signedly.api_response import ApiResponse
28
+ from signedly.rest import RESTResponseType
29
+
30
+
31
+ class APIRequestLogsApi:
32
+ """NOTE: This class is auto generated by OpenAPI Generator
33
+ Ref: https://openapi-generator.tech
34
+
35
+ Do not edit the class manually.
36
+ """
37
+
38
+ def __init__(self, api_client=None) -> None:
39
+ if api_client is None:
40
+ api_client = ApiClient.get_default()
41
+ self.api_client = api_client
42
+
43
+
44
+ @validate_call
45
+ def list_request_counts(
46
+ self,
47
+ method: Annotated[Optional[StrictStr], Field(description="Only this HTTP method.")] = None,
48
+ path: Annotated[Optional[StrictStr], Field(description="Only paths that contain this, e.g. `/ap1/document/`.")] = None,
49
+ limit: Annotated[Optional[StrictInt], Field(description="How many results to return (default 10).")] = None,
50
+ offset: Annotated[Optional[StrictInt], Field(description="How many results to skip.")] = None,
51
+ _request_timeout: Union[
52
+ None,
53
+ Annotated[StrictFloat, Field(gt=0)],
54
+ Tuple[
55
+ Annotated[StrictFloat, Field(gt=0)],
56
+ Annotated[StrictFloat, Field(gt=0)]
57
+ ]
58
+ ] = None,
59
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
60
+ _content_type: Optional[StrictStr] = None,
61
+ _headers: Optional[Dict[StrictStr, Any]] = None,
62
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
63
+ ) -> RequestCountPage:
64
+ """Count your API calls per path
65
+
66
+ How many calls this API client has made to each path and method, most recently used first. Paged: see `limit` and `offset`.
67
+
68
+ :param method: Only this HTTP method.
69
+ :type method: str
70
+ :param path: Only paths that contain this, e.g. `/ap1/document/`.
71
+ :type path: str
72
+ :param limit: How many results to return (default 10).
73
+ :type limit: int
74
+ :param offset: How many results to skip.
75
+ :type offset: int
76
+ :param _request_timeout: timeout setting for this request. If one
77
+ number provided, it will be total request
78
+ timeout. It can also be a pair (tuple) of
79
+ (connection, read) timeouts.
80
+ :type _request_timeout: int, tuple(int, int), optional
81
+ :param _request_auth: set to override the auth_settings for an a single
82
+ request; this effectively ignores the
83
+ authentication in the spec for a single request.
84
+ :type _request_auth: dict, optional
85
+ :param _content_type: force content-type for the request.
86
+ :type _content_type: str, Optional
87
+ :param _headers: set to override the headers for a single
88
+ request; this effectively ignores the headers
89
+ in the spec for a single request.
90
+ :type _headers: dict, optional
91
+ :param _host_index: set to override the host_index for a single
92
+ request; this effectively ignores the host_index
93
+ in the spec for a single request.
94
+ :type _host_index: int, optional
95
+ :return: Returns the result object.
96
+ """ # noqa: E501
97
+
98
+ _param = self._list_request_counts_serialize(
99
+ method=method,
100
+ path=path,
101
+ limit=limit,
102
+ offset=offset,
103
+ _request_auth=_request_auth,
104
+ _content_type=_content_type,
105
+ _headers=_headers,
106
+ _host_index=_host_index
107
+ )
108
+
109
+ _response_types_map: Dict[str, Optional[str]] = {
110
+ '200': "RequestCountPage",
111
+ }
112
+ response_data = self.api_client.call_api(
113
+ *_param,
114
+ _request_timeout=_request_timeout
115
+ )
116
+ response_data.read()
117
+ return self.api_client.response_deserialize(
118
+ response_data=response_data,
119
+ response_types_map=_response_types_map,
120
+ ).data
121
+
122
+
123
+ @validate_call
124
+ def list_request_counts_with_http_info(
125
+ self,
126
+ method: Annotated[Optional[StrictStr], Field(description="Only this HTTP method.")] = None,
127
+ path: Annotated[Optional[StrictStr], Field(description="Only paths that contain this, e.g. `/ap1/document/`.")] = None,
128
+ limit: Annotated[Optional[StrictInt], Field(description="How many results to return (default 10).")] = None,
129
+ offset: Annotated[Optional[StrictInt], Field(description="How many results to skip.")] = None,
130
+ _request_timeout: Union[
131
+ None,
132
+ Annotated[StrictFloat, Field(gt=0)],
133
+ Tuple[
134
+ Annotated[StrictFloat, Field(gt=0)],
135
+ Annotated[StrictFloat, Field(gt=0)]
136
+ ]
137
+ ] = None,
138
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
139
+ _content_type: Optional[StrictStr] = None,
140
+ _headers: Optional[Dict[StrictStr, Any]] = None,
141
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
142
+ ) -> ApiResponse[RequestCountPage]:
143
+ """Count your API calls per path
144
+
145
+ How many calls this API client has made to each path and method, most recently used first. Paged: see `limit` and `offset`.
146
+
147
+ :param method: Only this HTTP method.
148
+ :type method: str
149
+ :param path: Only paths that contain this, e.g. `/ap1/document/`.
150
+ :type path: str
151
+ :param limit: How many results to return (default 10).
152
+ :type limit: int
153
+ :param offset: How many results to skip.
154
+ :type offset: int
155
+ :param _request_timeout: timeout setting for this request. If one
156
+ number provided, it will be total request
157
+ timeout. It can also be a pair (tuple) of
158
+ (connection, read) timeouts.
159
+ :type _request_timeout: int, tuple(int, int), optional
160
+ :param _request_auth: set to override the auth_settings for an a single
161
+ request; this effectively ignores the
162
+ authentication in the spec for a single request.
163
+ :type _request_auth: dict, optional
164
+ :param _content_type: force content-type for the request.
165
+ :type _content_type: str, Optional
166
+ :param _headers: set to override the headers for a single
167
+ request; this effectively ignores the headers
168
+ in the spec for a single request.
169
+ :type _headers: dict, optional
170
+ :param _host_index: set to override the host_index for a single
171
+ request; this effectively ignores the host_index
172
+ in the spec for a single request.
173
+ :type _host_index: int, optional
174
+ :return: Returns the result object.
175
+ """ # noqa: E501
176
+
177
+ _param = self._list_request_counts_serialize(
178
+ method=method,
179
+ path=path,
180
+ limit=limit,
181
+ offset=offset,
182
+ _request_auth=_request_auth,
183
+ _content_type=_content_type,
184
+ _headers=_headers,
185
+ _host_index=_host_index
186
+ )
187
+
188
+ _response_types_map: Dict[str, Optional[str]] = {
189
+ '200': "RequestCountPage",
190
+ }
191
+ response_data = self.api_client.call_api(
192
+ *_param,
193
+ _request_timeout=_request_timeout
194
+ )
195
+ response_data.read()
196
+ return self.api_client.response_deserialize(
197
+ response_data=response_data,
198
+ response_types_map=_response_types_map,
199
+ )
200
+
201
+
202
+ @validate_call
203
+ def list_request_counts_without_preload_content(
204
+ self,
205
+ method: Annotated[Optional[StrictStr], Field(description="Only this HTTP method.")] = None,
206
+ path: Annotated[Optional[StrictStr], Field(description="Only paths that contain this, e.g. `/ap1/document/`.")] = None,
207
+ limit: Annotated[Optional[StrictInt], Field(description="How many results to return (default 10).")] = None,
208
+ offset: Annotated[Optional[StrictInt], Field(description="How many results to skip.")] = None,
209
+ _request_timeout: Union[
210
+ None,
211
+ Annotated[StrictFloat, Field(gt=0)],
212
+ Tuple[
213
+ Annotated[StrictFloat, Field(gt=0)],
214
+ Annotated[StrictFloat, Field(gt=0)]
215
+ ]
216
+ ] = None,
217
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
218
+ _content_type: Optional[StrictStr] = None,
219
+ _headers: Optional[Dict[StrictStr, Any]] = None,
220
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
221
+ ) -> RESTResponseType:
222
+ """Count your API calls per path
223
+
224
+ How many calls this API client has made to each path and method, most recently used first. Paged: see `limit` and `offset`.
225
+
226
+ :param method: Only this HTTP method.
227
+ :type method: str
228
+ :param path: Only paths that contain this, e.g. `/ap1/document/`.
229
+ :type path: str
230
+ :param limit: How many results to return (default 10).
231
+ :type limit: int
232
+ :param offset: How many results to skip.
233
+ :type offset: int
234
+ :param _request_timeout: timeout setting for this request. If one
235
+ number provided, it will be total request
236
+ timeout. It can also be a pair (tuple) of
237
+ (connection, read) timeouts.
238
+ :type _request_timeout: int, tuple(int, int), optional
239
+ :param _request_auth: set to override the auth_settings for an a single
240
+ request; this effectively ignores the
241
+ authentication in the spec for a single request.
242
+ :type _request_auth: dict, optional
243
+ :param _content_type: force content-type for the request.
244
+ :type _content_type: str, Optional
245
+ :param _headers: set to override the headers for a single
246
+ request; this effectively ignores the headers
247
+ in the spec for a single request.
248
+ :type _headers: dict, optional
249
+ :param _host_index: set to override the host_index for a single
250
+ request; this effectively ignores the host_index
251
+ in the spec for a single request.
252
+ :type _host_index: int, optional
253
+ :return: Returns the result object.
254
+ """ # noqa: E501
255
+
256
+ _param = self._list_request_counts_serialize(
257
+ method=method,
258
+ path=path,
259
+ limit=limit,
260
+ offset=offset,
261
+ _request_auth=_request_auth,
262
+ _content_type=_content_type,
263
+ _headers=_headers,
264
+ _host_index=_host_index
265
+ )
266
+
267
+ _response_types_map: Dict[str, Optional[str]] = {
268
+ '200': "RequestCountPage",
269
+ }
270
+ response_data = self.api_client.call_api(
271
+ *_param,
272
+ _request_timeout=_request_timeout
273
+ )
274
+ return response_data.response
275
+
276
+
277
+ def _list_request_counts_serialize(
278
+ self,
279
+ method,
280
+ path,
281
+ limit,
282
+ offset,
283
+ _request_auth,
284
+ _content_type,
285
+ _headers,
286
+ _host_index,
287
+ ) -> RequestSerialized:
288
+
289
+ _host = None
290
+
291
+ _collection_formats: Dict[str, str] = {
292
+ }
293
+
294
+ _path_params: Dict[str, str] = {}
295
+ _query_params: List[Tuple[str, str]] = []
296
+ _header_params: Dict[str, Optional[str]] = _headers or {}
297
+ _form_params: List[Tuple[str, str]] = []
298
+ _files: Dict[
299
+ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
300
+ ] = {}
301
+ _body_params: Optional[bytes] = None
302
+
303
+ # process the path parameters
304
+ # process the query parameters
305
+ if method is not None:
306
+
307
+ _query_params.append(('method', method))
308
+
309
+ if path is not None:
310
+
311
+ _query_params.append(('path', path))
312
+
313
+ if limit is not None:
314
+
315
+ _query_params.append(('limit', limit))
316
+
317
+ if offset is not None:
318
+
319
+ _query_params.append(('offset', offset))
320
+
321
+ # process the header parameters
322
+ # process the form parameters
323
+ # process the body parameter
324
+
325
+
326
+ # set the HTTP header `Accept`
327
+ if 'Accept' not in _header_params:
328
+ _header_params['Accept'] = self.api_client.select_header_accept(
329
+ [
330
+ 'application/json'
331
+ ]
332
+ )
333
+
334
+
335
+ # authentication setting
336
+ _auth_settings: List[str] = [
337
+ 'Bearer'
338
+ ]
339
+
340
+ return self.api_client.param_serialize(
341
+ method='GET',
342
+ resource_path='/ap1/logs/hits/',
343
+ path_params=_path_params,
344
+ query_params=_query_params,
345
+ header_params=_header_params,
346
+ body=_body_params,
347
+ post_params=_form_params,
348
+ files=_files,
349
+ auth_settings=_auth_settings,
350
+ collection_formats=_collection_formats,
351
+ _host=_host,
352
+ _request_auth=_request_auth
353
+ )
354
+
355
+
356
+
357
+
358
+ @validate_call
359
+ def list_request_logs(
360
+ self,
361
+ method: Annotated[Optional[StrictStr], Field(description="Only this HTTP method.")] = None,
362
+ path: Annotated[Optional[StrictStr], Field(description="Only paths that contain this, e.g. `/ap1/document/`.")] = None,
363
+ ip_address: Annotated[Optional[StrictStr], Field(description="Only calls from this IP address.")] = None,
364
+ limit: Annotated[Optional[StrictInt], Field(description="How many results to return (default 10).")] = None,
365
+ offset: Annotated[Optional[StrictInt], Field(description="How many results to skip.")] = None,
366
+ _request_timeout: Union[
367
+ None,
368
+ Annotated[StrictFloat, Field(gt=0)],
369
+ Tuple[
370
+ Annotated[StrictFloat, Field(gt=0)],
371
+ Annotated[StrictFloat, Field(gt=0)]
372
+ ]
373
+ ] = None,
374
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
375
+ _content_type: Optional[StrictStr] = None,
376
+ _headers: Optional[Dict[StrictStr, Any]] = None,
377
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
378
+ ) -> RequestLogPage:
379
+ """List your API calls
380
+
381
+ This API client's calls, newest first, with their headers and bodies (credentials and tokens are redacted). Paged: see `limit` and `offset`.
382
+
383
+ :param method: Only this HTTP method.
384
+ :type method: str
385
+ :param path: Only paths that contain this, e.g. `/ap1/document/`.
386
+ :type path: str
387
+ :param ip_address: Only calls from this IP address.
388
+ :type ip_address: str
389
+ :param limit: How many results to return (default 10).
390
+ :type limit: int
391
+ :param offset: How many results to skip.
392
+ :type offset: int
393
+ :param _request_timeout: timeout setting for this request. If one
394
+ number provided, it will be total request
395
+ timeout. It can also be a pair (tuple) of
396
+ (connection, read) timeouts.
397
+ :type _request_timeout: int, tuple(int, int), optional
398
+ :param _request_auth: set to override the auth_settings for an a single
399
+ request; this effectively ignores the
400
+ authentication in the spec for a single request.
401
+ :type _request_auth: dict, optional
402
+ :param _content_type: force content-type for the request.
403
+ :type _content_type: str, Optional
404
+ :param _headers: set to override the headers for a single
405
+ request; this effectively ignores the headers
406
+ in the spec for a single request.
407
+ :type _headers: dict, optional
408
+ :param _host_index: set to override the host_index for a single
409
+ request; this effectively ignores the host_index
410
+ in the spec for a single request.
411
+ :type _host_index: int, optional
412
+ :return: Returns the result object.
413
+ """ # noqa: E501
414
+
415
+ _param = self._list_request_logs_serialize(
416
+ method=method,
417
+ path=path,
418
+ ip_address=ip_address,
419
+ limit=limit,
420
+ offset=offset,
421
+ _request_auth=_request_auth,
422
+ _content_type=_content_type,
423
+ _headers=_headers,
424
+ _host_index=_host_index
425
+ )
426
+
427
+ _response_types_map: Dict[str, Optional[str]] = {
428
+ '200': "RequestLogPage",
429
+ }
430
+ response_data = self.api_client.call_api(
431
+ *_param,
432
+ _request_timeout=_request_timeout
433
+ )
434
+ response_data.read()
435
+ return self.api_client.response_deserialize(
436
+ response_data=response_data,
437
+ response_types_map=_response_types_map,
438
+ ).data
439
+
440
+
441
+ @validate_call
442
+ def list_request_logs_with_http_info(
443
+ self,
444
+ method: Annotated[Optional[StrictStr], Field(description="Only this HTTP method.")] = None,
445
+ path: Annotated[Optional[StrictStr], Field(description="Only paths that contain this, e.g. `/ap1/document/`.")] = None,
446
+ ip_address: Annotated[Optional[StrictStr], Field(description="Only calls from this IP address.")] = None,
447
+ limit: Annotated[Optional[StrictInt], Field(description="How many results to return (default 10).")] = None,
448
+ offset: Annotated[Optional[StrictInt], Field(description="How many results to skip.")] = None,
449
+ _request_timeout: Union[
450
+ None,
451
+ Annotated[StrictFloat, Field(gt=0)],
452
+ Tuple[
453
+ Annotated[StrictFloat, Field(gt=0)],
454
+ Annotated[StrictFloat, Field(gt=0)]
455
+ ]
456
+ ] = None,
457
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
458
+ _content_type: Optional[StrictStr] = None,
459
+ _headers: Optional[Dict[StrictStr, Any]] = None,
460
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
461
+ ) -> ApiResponse[RequestLogPage]:
462
+ """List your API calls
463
+
464
+ This API client's calls, newest first, with their headers and bodies (credentials and tokens are redacted). Paged: see `limit` and `offset`.
465
+
466
+ :param method: Only this HTTP method.
467
+ :type method: str
468
+ :param path: Only paths that contain this, e.g. `/ap1/document/`.
469
+ :type path: str
470
+ :param ip_address: Only calls from this IP address.
471
+ :type ip_address: str
472
+ :param limit: How many results to return (default 10).
473
+ :type limit: int
474
+ :param offset: How many results to skip.
475
+ :type offset: int
476
+ :param _request_timeout: timeout setting for this request. If one
477
+ number provided, it will be total request
478
+ timeout. It can also be a pair (tuple) of
479
+ (connection, read) timeouts.
480
+ :type _request_timeout: int, tuple(int, int), optional
481
+ :param _request_auth: set to override the auth_settings for an a single
482
+ request; this effectively ignores the
483
+ authentication in the spec for a single request.
484
+ :type _request_auth: dict, optional
485
+ :param _content_type: force content-type for the request.
486
+ :type _content_type: str, Optional
487
+ :param _headers: set to override the headers for a single
488
+ request; this effectively ignores the headers
489
+ in the spec for a single request.
490
+ :type _headers: dict, optional
491
+ :param _host_index: set to override the host_index for a single
492
+ request; this effectively ignores the host_index
493
+ in the spec for a single request.
494
+ :type _host_index: int, optional
495
+ :return: Returns the result object.
496
+ """ # noqa: E501
497
+
498
+ _param = self._list_request_logs_serialize(
499
+ method=method,
500
+ path=path,
501
+ ip_address=ip_address,
502
+ limit=limit,
503
+ offset=offset,
504
+ _request_auth=_request_auth,
505
+ _content_type=_content_type,
506
+ _headers=_headers,
507
+ _host_index=_host_index
508
+ )
509
+
510
+ _response_types_map: Dict[str, Optional[str]] = {
511
+ '200': "RequestLogPage",
512
+ }
513
+ response_data = self.api_client.call_api(
514
+ *_param,
515
+ _request_timeout=_request_timeout
516
+ )
517
+ response_data.read()
518
+ return self.api_client.response_deserialize(
519
+ response_data=response_data,
520
+ response_types_map=_response_types_map,
521
+ )
522
+
523
+
524
+ @validate_call
525
+ def list_request_logs_without_preload_content(
526
+ self,
527
+ method: Annotated[Optional[StrictStr], Field(description="Only this HTTP method.")] = None,
528
+ path: Annotated[Optional[StrictStr], Field(description="Only paths that contain this, e.g. `/ap1/document/`.")] = None,
529
+ ip_address: Annotated[Optional[StrictStr], Field(description="Only calls from this IP address.")] = None,
530
+ limit: Annotated[Optional[StrictInt], Field(description="How many results to return (default 10).")] = None,
531
+ offset: Annotated[Optional[StrictInt], Field(description="How many results to skip.")] = None,
532
+ _request_timeout: Union[
533
+ None,
534
+ Annotated[StrictFloat, Field(gt=0)],
535
+ Tuple[
536
+ Annotated[StrictFloat, Field(gt=0)],
537
+ Annotated[StrictFloat, Field(gt=0)]
538
+ ]
539
+ ] = None,
540
+ _request_auth: Optional[Dict[StrictStr, Any]] = None,
541
+ _content_type: Optional[StrictStr] = None,
542
+ _headers: Optional[Dict[StrictStr, Any]] = None,
543
+ _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
544
+ ) -> RESTResponseType:
545
+ """List your API calls
546
+
547
+ This API client's calls, newest first, with their headers and bodies (credentials and tokens are redacted). Paged: see `limit` and `offset`.
548
+
549
+ :param method: Only this HTTP method.
550
+ :type method: str
551
+ :param path: Only paths that contain this, e.g. `/ap1/document/`.
552
+ :type path: str
553
+ :param ip_address: Only calls from this IP address.
554
+ :type ip_address: str
555
+ :param limit: How many results to return (default 10).
556
+ :type limit: int
557
+ :param offset: How many results to skip.
558
+ :type offset: int
559
+ :param _request_timeout: timeout setting for this request. If one
560
+ number provided, it will be total request
561
+ timeout. It can also be a pair (tuple) of
562
+ (connection, read) timeouts.
563
+ :type _request_timeout: int, tuple(int, int), optional
564
+ :param _request_auth: set to override the auth_settings for an a single
565
+ request; this effectively ignores the
566
+ authentication in the spec for a single request.
567
+ :type _request_auth: dict, optional
568
+ :param _content_type: force content-type for the request.
569
+ :type _content_type: str, Optional
570
+ :param _headers: set to override the headers for a single
571
+ request; this effectively ignores the headers
572
+ in the spec for a single request.
573
+ :type _headers: dict, optional
574
+ :param _host_index: set to override the host_index for a single
575
+ request; this effectively ignores the host_index
576
+ in the spec for a single request.
577
+ :type _host_index: int, optional
578
+ :return: Returns the result object.
579
+ """ # noqa: E501
580
+
581
+ _param = self._list_request_logs_serialize(
582
+ method=method,
583
+ path=path,
584
+ ip_address=ip_address,
585
+ limit=limit,
586
+ offset=offset,
587
+ _request_auth=_request_auth,
588
+ _content_type=_content_type,
589
+ _headers=_headers,
590
+ _host_index=_host_index
591
+ )
592
+
593
+ _response_types_map: Dict[str, Optional[str]] = {
594
+ '200': "RequestLogPage",
595
+ }
596
+ response_data = self.api_client.call_api(
597
+ *_param,
598
+ _request_timeout=_request_timeout
599
+ )
600
+ return response_data.response
601
+
602
+
603
+ def _list_request_logs_serialize(
604
+ self,
605
+ method,
606
+ path,
607
+ ip_address,
608
+ limit,
609
+ offset,
610
+ _request_auth,
611
+ _content_type,
612
+ _headers,
613
+ _host_index,
614
+ ) -> RequestSerialized:
615
+
616
+ _host = None
617
+
618
+ _collection_formats: Dict[str, str] = {
619
+ }
620
+
621
+ _path_params: Dict[str, str] = {}
622
+ _query_params: List[Tuple[str, str]] = []
623
+ _header_params: Dict[str, Optional[str]] = _headers or {}
624
+ _form_params: List[Tuple[str, str]] = []
625
+ _files: Dict[
626
+ str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
627
+ ] = {}
628
+ _body_params: Optional[bytes] = None
629
+
630
+ # process the path parameters
631
+ # process the query parameters
632
+ if method is not None:
633
+
634
+ _query_params.append(('method', method))
635
+
636
+ if path is not None:
637
+
638
+ _query_params.append(('path', path))
639
+
640
+ if ip_address is not None:
641
+
642
+ _query_params.append(('ip_address', ip_address))
643
+
644
+ if limit is not None:
645
+
646
+ _query_params.append(('limit', limit))
647
+
648
+ if offset is not None:
649
+
650
+ _query_params.append(('offset', offset))
651
+
652
+ # process the header parameters
653
+ # process the form parameters
654
+ # process the body parameter
655
+
656
+
657
+ # set the HTTP header `Accept`
658
+ if 'Accept' not in _header_params:
659
+ _header_params['Accept'] = self.api_client.select_header_accept(
660
+ [
661
+ 'application/json'
662
+ ]
663
+ )
664
+
665
+
666
+ # authentication setting
667
+ _auth_settings: List[str] = [
668
+ 'Bearer'
669
+ ]
670
+
671
+ return self.api_client.param_serialize(
672
+ method='GET',
673
+ resource_path='/ap1/logs/',
674
+ path_params=_path_params,
675
+ query_params=_query_params,
676
+ header_params=_header_params,
677
+ body=_body_params,
678
+ post_params=_form_params,
679
+ files=_files,
680
+ auth_settings=_auth_settings,
681
+ collection_formats=_collection_formats,
682
+ _host=_host,
683
+ _request_auth=_request_auth
684
+ )
685
+
686
+