logs-py 4.0.7__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.
- LOGS/Auxiliary/CheckClassName.py +1075 -0
- LOGS/Auxiliary/Constants.py +99 -0
- LOGS/Auxiliary/CustomEntityClassGenerator.py +254 -0
- LOGS/Auxiliary/CustomFieldClassGenerator.py +115 -0
- LOGS/Auxiliary/CustomFieldValueTypeChecker.py +168 -0
- LOGS/Auxiliary/CustomSectionClassGenerator.py +113 -0
- LOGS/Auxiliary/CustomTypeClassGenerator.py +147 -0
- LOGS/Auxiliary/DateTimeConverter.py +66 -0
- LOGS/Auxiliary/Decorators.py +109 -0
- LOGS/Auxiliary/Exceptions.py +341 -0
- LOGS/Auxiliary/LOGSErrorResponse.py +89 -0
- LOGS/Auxiliary/MinimalModelGenerator.py +236 -0
- LOGS/Auxiliary/ParameterHelper.py +56 -0
- LOGS/Auxiliary/ReplaceMessage.py +13 -0
- LOGS/Auxiliary/Tools.py +432 -0
- LOGS/Auxiliary/__init__.py +15 -0
- LOGS/Converter/Conversion.py +248 -0
- LOGS/Converter/Converter.py +96 -0
- LOGS/Converter/ConverterParameter.py +88 -0
- LOGS/Converter/DateTimeRange.py +58 -0
- LOGS/Converter/ExportParameters.py +89 -0
- LOGS/Converter/__init__.py +13 -0
- LOGS/Entities/Attachment.py +84 -0
- LOGS/Entities/AttachmentMinimal.py +8 -0
- LOGS/Entities/AttachmentRequestParameter.py +42 -0
- LOGS/Entities/Attachments.py +53 -0
- LOGS/Entities/AutoloadFileInfo.py +12 -0
- LOGS/Entities/AutoloadStatusError.py +7 -0
- LOGS/Entities/AxisNaming.py +33 -0
- LOGS/Entities/AxisZoom.py +33 -0
- LOGS/Entities/Bridge.py +165 -0
- LOGS/Entities/BridgeClientInfo.py +93 -0
- LOGS/Entities/BridgeMinimal.py +8 -0
- LOGS/Entities/BridgeRequestParameter.py +49 -0
- LOGS/Entities/BridgeType.py +7 -0
- LOGS/Entities/Bridges.py +12 -0
- LOGS/Entities/CustomField.py +243 -0
- LOGS/Entities/CustomFieldMinimal.py +8 -0
- LOGS/Entities/CustomFieldModels.py +111 -0
- LOGS/Entities/CustomFieldRequestParameter.py +69 -0
- LOGS/Entities/CustomFieldSearchQuery.py +40 -0
- LOGS/Entities/CustomFields.py +12 -0
- LOGS/Entities/CustomType.py +212 -0
- LOGS/Entities/CustomTypeMinimal.py +8 -0
- LOGS/Entities/CustomTypeRequestParameter.py +60 -0
- LOGS/Entities/CustomTypeSection.py +63 -0
- LOGS/Entities/CustomTypes.py +12 -0
- LOGS/Entities/DataFormat.py +97 -0
- LOGS/Entities/DataFormatInstrument.py +18 -0
- LOGS/Entities/DataFormatInstrumentMinimal.py +8 -0
- LOGS/Entities/DataFormatInstrumentRequestParameter.py +17 -0
- LOGS/Entities/DataFormatInstruments.py +16 -0
- LOGS/Entities/DataFormatMinimal.py +18 -0
- LOGS/Entities/DataFormatRequestParameter.py +21 -0
- LOGS/Entities/DataFormats.py +12 -0
- LOGS/Entities/DataSource.py +218 -0
- LOGS/Entities/DataSourceConnectionStatus.py +12 -0
- LOGS/Entities/DataSourceMinimal.py +8 -0
- LOGS/Entities/DataSourceRequestParameter.py +57 -0
- LOGS/Entities/DataSourceStatus.py +108 -0
- LOGS/Entities/DataSourceStatusIterator.py +16 -0
- LOGS/Entities/DataSourceStatusRequestParameter.py +31 -0
- LOGS/Entities/DataSources.py +12 -0
- LOGS/Entities/Dataset.py +439 -0
- LOGS/Entities/DatasetBase.py +196 -0
- LOGS/Entities/DatasetCreator.py +148 -0
- LOGS/Entities/DatasetInfo.py +147 -0
- LOGS/Entities/DatasetMatchTypes.py +157 -0
- LOGS/Entities/DatasetMatching.py +196 -0
- LOGS/Entities/DatasetMinimal.py +8 -0
- LOGS/Entities/DatasetModels.py +33 -0
- LOGS/Entities/DatasetRequestParameter.py +92 -0
- LOGS/Entities/DatasetTemplate.py +23 -0
- LOGS/Entities/DatasetUploadParameter.py +14 -0
- LOGS/Entities/Datasets.py +142 -0
- LOGS/Entities/Datatrack.py +179 -0
- LOGS/Entities/DatatrackFormattedTable.py +25 -0
- LOGS/Entities/DatatrackGeneric.py +34 -0
- LOGS/Entities/DatatrackImage.py +25 -0
- LOGS/Entities/DatatrackNumericArray.py +30 -0
- LOGS/Entities/DatatrackNumericMatrix.py +98 -0
- LOGS/Entities/Entities.py +71 -0
- LOGS/Entities/EntitiesRequestParameter.py +18 -0
- LOGS/Entities/EntityOriginWriteModelWithId.py +15 -0
- LOGS/Entities/FileEntry.py +138 -0
- LOGS/Entities/FileExcludePattern.py +8 -0
- LOGS/Entities/FormatMetaData.py +56 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTable.py +135 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableCell.py +108 -0
- LOGS/Entities/FormattedTable/DatatypeFormattedTableSettings.py +11 -0
- LOGS/Entities/FormattedTable/__init__.py +9 -0
- LOGS/Entities/HierarchyLeaf.py +15 -0
- LOGS/Entities/HierarchyNode.py +40 -0
- LOGS/Entities/ILiteraryTypedEntity.py +19 -0
- LOGS/Entities/InventoryItem.py +102 -0
- LOGS/Entities/InventoryItemMinimal.py +25 -0
- LOGS/Entities/InventoryItemRequestParameter.py +58 -0
- LOGS/Entities/InventoryItems.py +12 -0
- LOGS/Entities/LabNotebook.py +33 -0
- LOGS/Entities/LabNotebookEntries.py +16 -0
- LOGS/Entities/LabNotebookEntry.py +106 -0
- LOGS/Entities/LabNotebookEntryContent/BasicAttribute.py +15 -0
- LOGS/Entities/LabNotebookEntryContent/EntityAttribute.py +85 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBlockquote.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentBulletList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentCallout.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentContentPlaceholderNode.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentConverter.py +207 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentDocument.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntity.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentEntityMention.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHeading.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentHorizontalRule.py +12 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentItem.py +37 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentListItem.py +49 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentOrderedList.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentParagraph.py +13 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTable.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableCell.py +40 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTableRow.py +8 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskList.py +17 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentTaskListItem.py +31 -0
- LOGS/Entities/LabNotebookEntryContent/EntryContentText.py +33 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithAttribute.py +23 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithContent.py +38 -0
- LOGS/Entities/LabNotebookEntryContent/IEntryContentWithTextAttribute.py +16 -0
- LOGS/Entities/LabNotebookEntryContent/TextAttribute.py +46 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkAtributes.py +64 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarkConverter.py +45 -0
- LOGS/Entities/LabNotebookEntryContent/TextMarks.py +71 -0
- LOGS/Entities/LabNotebookEntryContent/__init__.py +34 -0
- LOGS/Entities/LabNotebookEntryMinimal.py +8 -0
- LOGS/Entities/LabNotebookEntryRequestParameter.py +59 -0
- LOGS/Entities/LabNotebookExperiment.py +58 -0
- LOGS/Entities/LabNotebookExperimentMinimal.py +8 -0
- LOGS/Entities/LabNotebookExperimentRequestParameter.py +52 -0
- LOGS/Entities/LabNotebookExperiments.py +16 -0
- LOGS/Entities/LabNotebookMinimal.py +8 -0
- LOGS/Entities/LabNotebookModels.py +14 -0
- LOGS/Entities/LabNotebookRequestParameter.py +42 -0
- LOGS/Entities/LabNotebookTemplate.py +42 -0
- LOGS/Entities/LabNotebookTemplateMinimal.py +8 -0
- LOGS/Entities/LabNotebookTemplateRequestParameter.py +38 -0
- LOGS/Entities/LabNotebookTemplates.py +16 -0
- LOGS/Entities/LabNotebooks.py +12 -0
- LOGS/Entities/Method.py +66 -0
- LOGS/Entities/MethodMinimal.py +8 -0
- LOGS/Entities/MethodRequestParameter.py +16 -0
- LOGS/Entities/Methods.py +12 -0
- LOGS/Entities/Origin.py +53 -0
- LOGS/Entities/OriginMinimal.py +8 -0
- LOGS/Entities/OriginRequestParameter.py +28 -0
- LOGS/Entities/Origins.py +12 -0
- LOGS/Entities/ParserLog.py +49 -0
- LOGS/Entities/Permission.py +9 -0
- LOGS/Entities/Person.py +145 -0
- LOGS/Entities/PersonCategory.py +12 -0
- LOGS/Entities/PersonMinimal.py +8 -0
- LOGS/Entities/PersonRequestParameter.py +58 -0
- LOGS/Entities/Persons.py +12 -0
- LOGS/Entities/Project.py +52 -0
- LOGS/Entities/ProjectMinimal.py +8 -0
- LOGS/Entities/ProjectPersonPermission.py +102 -0
- LOGS/Entities/ProjectRequestParameter.py +58 -0
- LOGS/Entities/Projects.py +12 -0
- LOGS/Entities/Role.py +94 -0
- LOGS/Entities/RoleMinimal.py +8 -0
- LOGS/Entities/RoleRequestParameter.py +40 -0
- LOGS/Entities/Roles.py +12 -0
- LOGS/Entities/RunState.py +9 -0
- LOGS/Entities/Sample.py +53 -0
- LOGS/Entities/SampleMinimal.py +8 -0
- LOGS/Entities/SampleRequestParameter.py +54 -0
- LOGS/Entities/Samples.py +12 -0
- LOGS/Entities/SharedContent.py +87 -0
- LOGS/Entities/SharedContentMinimal.py +8 -0
- LOGS/Entities/SharedContentRequestParameter.py +38 -0
- LOGS/Entities/SharedContents.py +12 -0
- LOGS/Entities/Signature.py +60 -0
- LOGS/Entities/Track.py +93 -0
- LOGS/Entities/TrackData.py +20 -0
- LOGS/Entities/TrackImage.py +21 -0
- LOGS/Entities/TrackImageData.py +20 -0
- LOGS/Entities/TrackMatrix.py +28 -0
- LOGS/Entities/TrackMatrixData.py +22 -0
- LOGS/Entities/TrackSettings.py +55 -0
- LOGS/Entities/TrackTable.py +21 -0
- LOGS/Entities/TrackTableData.py +22 -0
- LOGS/Entities/TrackXY.py +40 -0
- LOGS/Entities/TrackXYComplex.py +51 -0
- LOGS/Entities/TrackXYComplexData.py +50 -0
- LOGS/Entities/TrackXYData.py +31 -0
- LOGS/Entities/Vendor.py +40 -0
- LOGS/Entities/VendorMinimal.py +8 -0
- LOGS/Entities/VendorRequestParameter.py +17 -0
- LOGS/Entities/Vendors.py +12 -0
- LOGS/Entities/__init__.py +118 -0
- LOGS/Entity/ConnectedEntity.py +170 -0
- LOGS/Entity/Entity.py +203 -0
- LOGS/Entity/EntityConnector.py +70 -0
- LOGS/Entity/EntityIterator.py +263 -0
- LOGS/Entity/EntityMinimal.py +141 -0
- LOGS/Entity/EntityMinimalWithIntId.py +36 -0
- LOGS/Entity/EntityMinimalWithStrId.py +36 -0
- LOGS/Entity/EntityMinimalWithType.py +47 -0
- LOGS/Entity/EntityRequestParameter.py +104 -0
- LOGS/Entity/EntitySortBy.py +69 -0
- LOGS/Entity/EntityWithIntId.py +26 -0
- LOGS/Entity/EntityWithStrId.py +26 -0
- LOGS/Entity/IGenericEntityOrderBy.py +55 -0
- LOGS/Entity/IdIterator.py +207 -0
- LOGS/Entity/SerializableContent.py +834 -0
- LOGS/Entity/__init__.py +23 -0
- LOGS/Interfaces/ICustomFieldValue.py +92 -0
- LOGS/Interfaces/ICustomSectionValue.py +161 -0
- LOGS/Interfaces/ICustomTypeValue.py +152 -0
- LOGS/Interfaces/ICustomValue.py +28 -0
- LOGS/Interfaces/IEntityInterface.py +7 -0
- LOGS/Interfaces/IEntryRecord.py +57 -0
- LOGS/Interfaces/IHierarchicalEntity.py +41 -0
- LOGS/Interfaces/IHierarchyType.py +63 -0
- LOGS/Interfaces/ILockableEntity.py +52 -0
- LOGS/Interfaces/IModificationRecord.py +56 -0
- LOGS/Interfaces/INamedEntity.py +25 -0
- LOGS/Interfaces/IOwnedEntity.py +27 -0
- LOGS/Interfaces/IPaginationRequest.py +11 -0
- LOGS/Interfaces/IPermissionedEntity.py +72 -0
- LOGS/Interfaces/IProjectBased.py +27 -0
- LOGS/Interfaces/ISessionedEntity.py +59 -0
- LOGS/Interfaces/ISignableEntity.py +49 -0
- LOGS/Interfaces/ISoftDeletable.py +28 -0
- LOGS/Interfaces/ITypedEntity.py +129 -0
- LOGS/Interfaces/IUniqueEntity.py +61 -0
- LOGS/Interfaces/IVersionedEntity.py +39 -0
- LOGS/Interfaces/__init__.py +7 -0
- LOGS/LOGS.py +1436 -0
- LOGS/LOGSConnection.py +647 -0
- LOGS/LOGSOptions.py +11 -0
- LOGS/Parameters/Color.py +92 -0
- LOGS/Parameters/ParameterBase.py +55 -0
- LOGS/Parameters/ParameterConverter.py +24 -0
- LOGS/Parameters/ParameterElement.py +99 -0
- LOGS/Parameters/ParameterList.py +52 -0
- LOGS/Parameters/ParameterTable.py +64 -0
- LOGS/Parameters/__init__.py +13 -0
- LOGS/ServerMetaData.py +120 -0
- LOGS/__init__.py +12 -0
- logs_py-4.0.7.dist-info/METADATA +51 -0
- logs_py-4.0.7.dist-info/RECORD +251 -0
- logs_py-4.0.7.dist-info/WHEEL +5 -0
- logs_py-4.0.7.dist-info/top_level.txt +1 -0
LOGS/LOGSConnection.py
ADDED
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import random
|
|
3
|
+
import re
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Union, cast
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
from requests import Response
|
|
10
|
+
|
|
11
|
+
from LOGS.Auxiliary import LOGSException, Tools
|
|
12
|
+
from LOGS.Auxiliary.LOGSErrorResponse import LOGSErrorResponse
|
|
13
|
+
from LOGS.Entities.FileEntry import FileEntry
|
|
14
|
+
from LOGS.LOGSOptions import LOGSOptions
|
|
15
|
+
from LOGS.ServerMetaData import ServerMetaData
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ResponseTypes(Enum):
|
|
19
|
+
RAW = "raw"
|
|
20
|
+
JSON = "json"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
RESPONSE_TYPES = Union[bytes, Dict[Any, Any], Response, str]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class MultipartEntry:
|
|
28
|
+
name: str
|
|
29
|
+
fileName: Optional[str]
|
|
30
|
+
content: Union[str, dict, FileEntry]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class LOGSConnection:
|
|
34
|
+
"""Python class to access the LOGS web API"""
|
|
35
|
+
|
|
36
|
+
_noErrorStates = set([200, 201, 204])
|
|
37
|
+
_compatibleAPIVersions = set(["4.0"])
|
|
38
|
+
# _compatibleAPIVersions = set(["1.1"])
|
|
39
|
+
__urlRe = re.compile(r"(?:(https*)\:\/\/)*([^\/:]+)(?:\:(\d+))*(?:\/(.*))*")
|
|
40
|
+
__urlApiRe = re.compile(r"api\/(\d+\.\d+)")
|
|
41
|
+
_port: Optional[int]
|
|
42
|
+
_connected: bool
|
|
43
|
+
_metadata: ServerMetaData
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
url: str,
|
|
48
|
+
apiKey: str,
|
|
49
|
+
use_internal: bool = False,
|
|
50
|
+
options: Optional[LOGSOptions] = None,
|
|
51
|
+
verify: bool = True,
|
|
52
|
+
):
|
|
53
|
+
"""Checks the connection to the server on creation
|
|
54
|
+
|
|
55
|
+
:param url: URL to specific LOGS group (e.g. https://mylogs/mygroup or https://mylogs:80/mygroup/api/0.1)
|
|
56
|
+
:param api_key: The API key that grants access to LOGS (you need to generate on in LOGS and copy it)
|
|
57
|
+
:param verbose: If set you see some information about the server connection. Defaults to False.
|
|
58
|
+
|
|
59
|
+
:raises Exception: URL does not defined or is invalid.
|
|
60
|
+
:raises Exception: The URL does not define a group.
|
|
61
|
+
:raises Exception: Server cannot be reached.
|
|
62
|
+
"""
|
|
63
|
+
self._options = Tools.checkAndConvert(
|
|
64
|
+
options, LOGSOptions, "options", initOnNone=True
|
|
65
|
+
)
|
|
66
|
+
self.promptPrefix = "LOGSAPI>"
|
|
67
|
+
|
|
68
|
+
self.url = url
|
|
69
|
+
|
|
70
|
+
if self._options.showServerInfo:
|
|
71
|
+
self.printServerStatus()
|
|
72
|
+
|
|
73
|
+
self._apiKey = apiKey
|
|
74
|
+
self._useInternal = use_internal
|
|
75
|
+
self._verify = verify
|
|
76
|
+
self._connected = False
|
|
77
|
+
self._metadata = ServerMetaData()
|
|
78
|
+
|
|
79
|
+
self.checkServer()
|
|
80
|
+
|
|
81
|
+
def printServerStatus(self):
|
|
82
|
+
print(self.promptPrefix, "Server properties:")
|
|
83
|
+
print(self.promptPrefix, " protocol:", self._protocol)
|
|
84
|
+
print(self.promptPrefix, " server:", self._server)
|
|
85
|
+
print(self.promptPrefix, " port:", self._port)
|
|
86
|
+
print(self.promptPrefix, " group:", self._group)
|
|
87
|
+
|
|
88
|
+
def setUrl(self, url):
|
|
89
|
+
match = self.__urlRe.search(url)
|
|
90
|
+
protocol = "http"
|
|
91
|
+
version = "0.1"
|
|
92
|
+
if not match:
|
|
93
|
+
raise Exception("Invalid URL '%s'." % url)
|
|
94
|
+
else:
|
|
95
|
+
(protocol, server, portStr, endpoints) = match.groups()
|
|
96
|
+
if endpoints:
|
|
97
|
+
group = endpoints.split("/")[0]
|
|
98
|
+
else:
|
|
99
|
+
group = None
|
|
100
|
+
if server == None or server == "":
|
|
101
|
+
raise Exception("URL must define a server.")
|
|
102
|
+
if group == None or group == "":
|
|
103
|
+
raise Exception("URL must contain a group.")
|
|
104
|
+
|
|
105
|
+
if portStr == None or portStr == "":
|
|
106
|
+
port = None
|
|
107
|
+
else:
|
|
108
|
+
port = int(portStr)
|
|
109
|
+
|
|
110
|
+
match = self.__urlApiRe.search(endpoints)
|
|
111
|
+
if match:
|
|
112
|
+
version = match.group(1)
|
|
113
|
+
|
|
114
|
+
# print("match", (protocol, server, port, group, version))
|
|
115
|
+
|
|
116
|
+
self._version = version
|
|
117
|
+
self._protocol = protocol
|
|
118
|
+
self._server = server
|
|
119
|
+
self._port = port
|
|
120
|
+
self._group = group
|
|
121
|
+
# self._url = url
|
|
122
|
+
|
|
123
|
+
def checkServer(self):
|
|
124
|
+
"""Check if server can be reached
|
|
125
|
+
|
|
126
|
+
:raises Exception: Server cannot be reached.
|
|
127
|
+
"""
|
|
128
|
+
testEndpoint = ["version", "detail"]
|
|
129
|
+
|
|
130
|
+
result, error = self.getEndpoint(testEndpoint)
|
|
131
|
+
url = result["url"] if isinstance(result, dict) else self.url
|
|
132
|
+
if error:
|
|
133
|
+
raise LOGSException(
|
|
134
|
+
"Could not connect to '%s': %s" % (url, error.errorString())
|
|
135
|
+
)
|
|
136
|
+
if self._options.showServerInfo:
|
|
137
|
+
print(
|
|
138
|
+
self.promptPrefix,
|
|
139
|
+
"Connection to server '%s://%s%s' successful."
|
|
140
|
+
% (
|
|
141
|
+
self.protocol,
|
|
142
|
+
self.server,
|
|
143
|
+
":" + str(self.port) if self.port else "",
|
|
144
|
+
),
|
|
145
|
+
)
|
|
146
|
+
self._connected = True
|
|
147
|
+
|
|
148
|
+
if isinstance(result, dict):
|
|
149
|
+
self._metadata = ServerMetaData(ref=result)
|
|
150
|
+
if (
|
|
151
|
+
not self._metadata.apiVersion
|
|
152
|
+
or self._metadata.apiVersion not in self._compatibleAPIVersions
|
|
153
|
+
):
|
|
154
|
+
raise LOGSException(
|
|
155
|
+
"This library is not compatible with the LOGS API version '%s'. (Expected %s %s)"
|
|
156
|
+
% (
|
|
157
|
+
(
|
|
158
|
+
self._metadata.apiVersion
|
|
159
|
+
if self._metadata.apiVersion
|
|
160
|
+
else "unknown"
|
|
161
|
+
),
|
|
162
|
+
(
|
|
163
|
+
"one of versions"
|
|
164
|
+
if len(self._compatibleAPIVersions) > 1
|
|
165
|
+
else "version"
|
|
166
|
+
),
|
|
167
|
+
Tools.eclipsesJoin(", ", list(self._compatibleAPIVersions)),
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
else:
|
|
171
|
+
raise LOGSException(
|
|
172
|
+
"Server '%s' could be reached but behaved unexpectedly." % (url, error)
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
def getUIUrl(self) -> str:
|
|
176
|
+
"""Generate full API URL
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
str: The url of the connected LOGS API (e.g. https://logs.com/api/2.1)
|
|
180
|
+
"""
|
|
181
|
+
return "%s://%s%s/%s" % (
|
|
182
|
+
self.protocol,
|
|
183
|
+
self.server,
|
|
184
|
+
":" + str(self.port) if self.port else "",
|
|
185
|
+
self.group,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
def getAPIUrl(self) -> str:
|
|
189
|
+
"""Generate full API URL
|
|
190
|
+
|
|
191
|
+
:return: The url of the connected LOGS API (e.g. https://logs.com/api/2.1)
|
|
192
|
+
"""
|
|
193
|
+
return "%s://%s%s/%s/api/%s" % (
|
|
194
|
+
self.protocol,
|
|
195
|
+
self.server,
|
|
196
|
+
":" + str(self.port) if self.port else "",
|
|
197
|
+
self.group,
|
|
198
|
+
self.version,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def getUIEndpointUrl(
|
|
202
|
+
self, endpoint: Union[Union[str, int], Sequence[Union[str, int]]]
|
|
203
|
+
) -> str:
|
|
204
|
+
"""Generate full API URL for a given endpoint
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
str: The url of the connected LOGS API (for dataset endpoint e.g. https://logs.com/api/2.1/dataset)
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
if isinstance(endpoint, list):
|
|
211
|
+
endpoint = "/".join([str(e) for e in endpoint])
|
|
212
|
+
|
|
213
|
+
return self.getUIUrl() + "/" + str(endpoint)
|
|
214
|
+
|
|
215
|
+
def getEndpointUrl(
|
|
216
|
+
self, endpoint: Union[Union[str, int], Sequence[Union[str, int]]]
|
|
217
|
+
) -> str:
|
|
218
|
+
"""Generate full API URL for a given endpoint
|
|
219
|
+
|
|
220
|
+
:return: The url of the connected LOGS API (for dataset endpoint e.g. https://logs.com/api/2.1/dataset)
|
|
221
|
+
"""
|
|
222
|
+
|
|
223
|
+
if isinstance(endpoint, list):
|
|
224
|
+
endpoint = "/".join([str(e) for e in endpoint])
|
|
225
|
+
|
|
226
|
+
return self.getAPIUrl() + "/" + str(endpoint)
|
|
227
|
+
|
|
228
|
+
def getUrl(
|
|
229
|
+
self,
|
|
230
|
+
url: str,
|
|
231
|
+
parameters: Optional[dict] = None,
|
|
232
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
233
|
+
includeUrl: bool = True,
|
|
234
|
+
):
|
|
235
|
+
"""Generate full API URL with GET parameters
|
|
236
|
+
|
|
237
|
+
:param url: Specify an API url otherwise object internal is used. Defaults to None.
|
|
238
|
+
:param parameters: Parameters to pass to an GET request. Defaults to None.
|
|
239
|
+
:param responseType: The return value is converted to the specified format. Defaults to "json".
|
|
240
|
+
:param includeUrl:
|
|
241
|
+
|
|
242
|
+
:return: The response of the server and the error code.
|
|
243
|
+
"""
|
|
244
|
+
if self._options.showRequestUrl:
|
|
245
|
+
paramString = ""
|
|
246
|
+
if parameters:
|
|
247
|
+
paramString = " ".join(
|
|
248
|
+
("%s:%s" % (k, v))
|
|
249
|
+
for k, v in parameters.items()
|
|
250
|
+
if v != None and v != ""
|
|
251
|
+
)
|
|
252
|
+
print(
|
|
253
|
+
self.promptPrefix,
|
|
254
|
+
"GET: %s %s" % (url, "{" + paramString + "}" if paramString else ""),
|
|
255
|
+
)
|
|
256
|
+
if self._options.showRequestHeader:
|
|
257
|
+
print(self.promptPrefix, "HEADER: %s" % self.getHeader())
|
|
258
|
+
|
|
259
|
+
# print("params", params)
|
|
260
|
+
response = requests.get(
|
|
261
|
+
url, headers=self.getHeader(), params=parameters, verify=self._verify
|
|
262
|
+
)
|
|
263
|
+
# print("URL:", response.url)
|
|
264
|
+
|
|
265
|
+
# if response == None:
|
|
266
|
+
# response =
|
|
267
|
+
# print("url", url)
|
|
268
|
+
return self.__convertResponse(response, responseType, includeUrl)
|
|
269
|
+
|
|
270
|
+
def getHeader(self) -> Dict[str, str]:
|
|
271
|
+
header = {"X-Api-Key": self.apiKey}
|
|
272
|
+
|
|
273
|
+
if self._useInternal:
|
|
274
|
+
header["X-LOGS-internal"] = "true"
|
|
275
|
+
|
|
276
|
+
if self._options.proxyTargetUrl:
|
|
277
|
+
header["X-Target-Backend"] = self._options.proxyTargetUrl
|
|
278
|
+
|
|
279
|
+
return header
|
|
280
|
+
|
|
281
|
+
def deleteUrl(
|
|
282
|
+
self,
|
|
283
|
+
url: str,
|
|
284
|
+
parameters: dict = {},
|
|
285
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
286
|
+
includeUrl: bool = True,
|
|
287
|
+
):
|
|
288
|
+
"""Generate full API URL with PUT body
|
|
289
|
+
|
|
290
|
+
:param url: Specify an API url otherwise object internal is used. Defaults to None.
|
|
291
|
+
:param params: Parameters to pass to an PUT request as json body. Defaults to None.
|
|
292
|
+
:param mode: The return value is converted to the specified format. Defaults to "json".
|
|
293
|
+
|
|
294
|
+
:return: The response of the server and the error code.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
if self._options.showRequestUrl:
|
|
298
|
+
print(self.promptPrefix, "DELETE: %s" % url)
|
|
299
|
+
if self._options.showRequestHeader:
|
|
300
|
+
print(self.promptPrefix, "HEADER: %s" % self.getHeader())
|
|
301
|
+
|
|
302
|
+
response = requests.delete(
|
|
303
|
+
url, headers=self.getHeader(), params=parameters, verify=self._verify
|
|
304
|
+
)
|
|
305
|
+
return self.__convertResponse(response, responseType, includeUrl=includeUrl)
|
|
306
|
+
|
|
307
|
+
def putUrl(
|
|
308
|
+
self,
|
|
309
|
+
url: str,
|
|
310
|
+
data: Union[dict, list] = {},
|
|
311
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
312
|
+
):
|
|
313
|
+
"""Generate full API URL with PUT body
|
|
314
|
+
|
|
315
|
+
:param url: Specify an API url otherwise object internal is used. Defaults to None.
|
|
316
|
+
:param params: Parameters to pass to an PUT request as json body. Defaults to None.
|
|
317
|
+
:param mode: The return value is converted to the specified format. Defaults to "json".
|
|
318
|
+
|
|
319
|
+
:return: The response of the server and the error code.
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
if self._options.showRequestUrl:
|
|
323
|
+
print(self.promptPrefix, "PUT: %s" % url)
|
|
324
|
+
if self._options.showRequestHeader:
|
|
325
|
+
print(self.promptPrefix, "HEADER: %s" % self.getHeader())
|
|
326
|
+
|
|
327
|
+
if self._options.showRequestBody:
|
|
328
|
+
print(self.promptPrefix, "BODY: %s" % self.__convertBody(data))
|
|
329
|
+
|
|
330
|
+
response = requests.put(
|
|
331
|
+
url, headers=self.getHeader(), json=data, verify=self._verify
|
|
332
|
+
)
|
|
333
|
+
return self.__convertResponse(response, responseType)
|
|
334
|
+
|
|
335
|
+
def putEndpoint(
|
|
336
|
+
self,
|
|
337
|
+
endpoint: Union[Union[str, int], Sequence[Union[str, int]]],
|
|
338
|
+
data: Union[dict, list] = {},
|
|
339
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
340
|
+
) -> Tuple[Optional[RESPONSE_TYPES], Optional[LOGSErrorResponse]]:
|
|
341
|
+
"""Connects to the API with PUT access to given endpoint
|
|
342
|
+
|
|
343
|
+
:param endpoint: Name of the endpoint (e.g. dataset/2/tracks)
|
|
344
|
+
:param params: Parameters to pass to the endpoint as json body. Defaults to None.
|
|
345
|
+
|
|
346
|
+
:return: The response of the server and the error code.
|
|
347
|
+
"""
|
|
348
|
+
url = self.getEndpointUrl(endpoint)
|
|
349
|
+
|
|
350
|
+
return self.putUrl(url, data, responseType)
|
|
351
|
+
|
|
352
|
+
def postMultipartUrl(
|
|
353
|
+
self,
|
|
354
|
+
url: str,
|
|
355
|
+
data: List[MultipartEntry] = [],
|
|
356
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
357
|
+
):
|
|
358
|
+
if self._options.showRequestUrl:
|
|
359
|
+
print(self.promptPrefix, "POST: %s" % url)
|
|
360
|
+
if self._options.showRequestHeader:
|
|
361
|
+
print(self.promptPrefix, "HEADER: %s" % self.getHeader())
|
|
362
|
+
|
|
363
|
+
if self._options.showRequestBody:
|
|
364
|
+
separator = "-" * 29 + "".join(
|
|
365
|
+
[str(random.randint(0, 9)) for _ in range(29)]
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
files = []
|
|
369
|
+
for entry in data:
|
|
370
|
+
content: Any = ""
|
|
371
|
+
if isinstance(entry.content, FileEntry):
|
|
372
|
+
# content = entry.content.toJson(compact=True)
|
|
373
|
+
with open(entry.content.path, "rb") as read:
|
|
374
|
+
content = read.read()
|
|
375
|
+
else:
|
|
376
|
+
content = json.dumps(entry.content)
|
|
377
|
+
|
|
378
|
+
if self._options.showRequestBody:
|
|
379
|
+
print(self.promptPrefix, "BODY: %s" % separator)
|
|
380
|
+
print(
|
|
381
|
+
self.promptPrefix,
|
|
382
|
+
"BODY: %s"
|
|
383
|
+
% "Content-Disposition: form-data; name='entry.fileName'",
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
c = (
|
|
387
|
+
str(content[:100]) + "..."
|
|
388
|
+
if isinstance(content, bytes) and len(content) > 100
|
|
389
|
+
else content
|
|
390
|
+
)
|
|
391
|
+
print(self.promptPrefix, "BODY: %s" % c)
|
|
392
|
+
|
|
393
|
+
files.append((entry.name, (entry.fileName, content)))
|
|
394
|
+
|
|
395
|
+
#### For checking the request
|
|
396
|
+
# request = requests.Request(
|
|
397
|
+
# "POST", "http://localhost:900/sandbox/api/0.1/datasets/create", files=files
|
|
398
|
+
# ).prepare()
|
|
399
|
+
# print(cast(Any, request.body).decode("ascii", "ignore"))
|
|
400
|
+
|
|
401
|
+
response = requests.post(
|
|
402
|
+
url, headers=self.getHeader(), files=files, verify=self._verify
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
return self.__convertResponse(response, responseType)
|
|
406
|
+
|
|
407
|
+
def postUrl(
|
|
408
|
+
self,
|
|
409
|
+
url: str,
|
|
410
|
+
data: Union[dict, list] = {},
|
|
411
|
+
parameters: Optional[dict] = None,
|
|
412
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
413
|
+
includeUrl: bool = True,
|
|
414
|
+
):
|
|
415
|
+
"""Generate full API URL with PUT body
|
|
416
|
+
|
|
417
|
+
:param url: Specify an API url otherwise object internal is used. Defaults to None.
|
|
418
|
+
:param params: Parameters to pass to an PUT request as json body. Defaults to None.
|
|
419
|
+
:param mode: The return value is converted to the specified format. Defaults to "json".
|
|
420
|
+
|
|
421
|
+
:return: The response of the server and the error code.
|
|
422
|
+
"""
|
|
423
|
+
if self._options.showRequestUrl:
|
|
424
|
+
paramString = ""
|
|
425
|
+
if parameters:
|
|
426
|
+
paramString = " ".join(
|
|
427
|
+
("%s:%s" % (k, v))
|
|
428
|
+
for k, v in parameters.items()
|
|
429
|
+
if v != None and v != ""
|
|
430
|
+
)
|
|
431
|
+
print(
|
|
432
|
+
self.promptPrefix,
|
|
433
|
+
"POST: %s %s" % (url, "{" + paramString + "}" if paramString else ""),
|
|
434
|
+
)
|
|
435
|
+
if self._options.showRequestHeader:
|
|
436
|
+
print(self.promptPrefix, "HEADER: %s" % self.getHeader())
|
|
437
|
+
|
|
438
|
+
if self._options.showRequestBody:
|
|
439
|
+
print(self.promptPrefix, "BODY: %s" % self.__convertBody(data))
|
|
440
|
+
|
|
441
|
+
response = requests.post(
|
|
442
|
+
url,
|
|
443
|
+
headers=self.getHeader(),
|
|
444
|
+
params=parameters,
|
|
445
|
+
json=data,
|
|
446
|
+
verify=self._verify,
|
|
447
|
+
)
|
|
448
|
+
return self.__convertResponse(response, responseType, includeUrl)
|
|
449
|
+
|
|
450
|
+
def postMultipartEndpoint(
|
|
451
|
+
self,
|
|
452
|
+
endpoint: Union[Union[str, int], Sequence[Union[str, int]]],
|
|
453
|
+
data: List[MultipartEntry] = [],
|
|
454
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
455
|
+
):
|
|
456
|
+
url = self.getEndpointUrl(endpoint)
|
|
457
|
+
|
|
458
|
+
return self.postMultipartUrl(url, data, responseType)
|
|
459
|
+
|
|
460
|
+
def postEndpoint(
|
|
461
|
+
self,
|
|
462
|
+
endpoint: Union[Union[str, int], Sequence[Union[str, int]]],
|
|
463
|
+
parameters: Optional[dict] = None,
|
|
464
|
+
data: Union[dict, list] = {},
|
|
465
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
466
|
+
):
|
|
467
|
+
"""Connects to the API with PUT access to given endpoint
|
|
468
|
+
|
|
469
|
+
:param endpoint: Name of the endpoint (e.g. dataset/2/tracks)
|
|
470
|
+
:param params: Parameters to pass to the endpoint as json body. Defaults to None.
|
|
471
|
+
|
|
472
|
+
:return: The response of the server and the error code.
|
|
473
|
+
"""
|
|
474
|
+
url = self.getEndpointUrl(endpoint)
|
|
475
|
+
|
|
476
|
+
return self.postUrl(
|
|
477
|
+
url=url, data=data, parameters=parameters, responseType=responseType
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
def deleteEndpoint(
|
|
481
|
+
self,
|
|
482
|
+
endpoint: Union[Union[str, int], Sequence[Union[str, int]]],
|
|
483
|
+
parameters: dict = {},
|
|
484
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
485
|
+
includeUrl: bool = True,
|
|
486
|
+
):
|
|
487
|
+
"""Connects to the API with DELETE access to given endpoint
|
|
488
|
+
|
|
489
|
+
:param endpoint: Name of the endpoint (e.g. dataset/2/tracks)
|
|
490
|
+
:param params: Parameters to pass to the endpoint. Defaults to None.
|
|
491
|
+
:param mode: Convert result to this format. Defaults to None.
|
|
492
|
+
|
|
493
|
+
:return: The response of the server and the error code.
|
|
494
|
+
"""
|
|
495
|
+
# print("Headers:", headers)
|
|
496
|
+
# print("Params:", params)
|
|
497
|
+
url = self.getEndpointUrl(endpoint)
|
|
498
|
+
|
|
499
|
+
return self.deleteUrl(
|
|
500
|
+
url, parameters=parameters, responseType=responseType, includeUrl=includeUrl
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
def getEndpoint(
|
|
504
|
+
self,
|
|
505
|
+
endpoint: Union[Union[str, int], Sequence[Union[str, int]]],
|
|
506
|
+
parameters: Optional[dict] = None,
|
|
507
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
508
|
+
includeUrl: bool = True,
|
|
509
|
+
) -> Tuple[Optional[RESPONSE_TYPES], Optional[LOGSErrorResponse]]:
|
|
510
|
+
"""Connects to the API with GET access to given endpoint
|
|
511
|
+
|
|
512
|
+
:param endpoint: Name of the endpoint (e.g. dataset/2/tracks)
|
|
513
|
+
:param params: Parameters to pass to the endpoint. Defaults to None.
|
|
514
|
+
:param mode: Convert result to this format. Defaults to None.
|
|
515
|
+
|
|
516
|
+
:return: The response of the server and the error code.
|
|
517
|
+
"""
|
|
518
|
+
# print("Headers:", headers)
|
|
519
|
+
# print("Params:", params)
|
|
520
|
+
url = self.getEndpointUrl(endpoint)
|
|
521
|
+
# print("URL:", url)
|
|
522
|
+
# print("Params:", params)
|
|
523
|
+
|
|
524
|
+
return self.getUrl(
|
|
525
|
+
url, parameters=parameters, responseType=responseType, includeUrl=includeUrl
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
# header = {"X-Api-Key": api_key}
|
|
529
|
+
|
|
530
|
+
# # try:
|
|
531
|
+
# response = requests.get(url, headers=header, params=params, verify=False, verify=self._verify)
|
|
532
|
+
# # except ValueError as error:
|
|
533
|
+
# # print(error)
|
|
534
|
+
# return self.convertResponse(response, mode)
|
|
535
|
+
|
|
536
|
+
# def convertCustomFieldParams(self, params: dict):
|
|
537
|
+
# # print(">", params)
|
|
538
|
+
# return {"customFields[%s]" % k: v for k, v in params.items()}
|
|
539
|
+
|
|
540
|
+
@classmethod
|
|
541
|
+
def __convertBody(cls, body) -> str:
|
|
542
|
+
if body == None:
|
|
543
|
+
return "None"
|
|
544
|
+
if isinstance(body, dict) or isinstance(body, list):
|
|
545
|
+
return json.dumps(body)
|
|
546
|
+
return body
|
|
547
|
+
|
|
548
|
+
def __convertResponse(
|
|
549
|
+
self,
|
|
550
|
+
response: Response,
|
|
551
|
+
responseType: ResponseTypes = ResponseTypes.JSON,
|
|
552
|
+
includeUrl: bool = True,
|
|
553
|
+
) -> Tuple[Optional[RESPONSE_TYPES], Optional[LOGSErrorResponse]]:
|
|
554
|
+
if response.status_code >= 200 and response.status_code < 300:
|
|
555
|
+
if responseType == ResponseTypes.RAW:
|
|
556
|
+
return response.content, None
|
|
557
|
+
else:
|
|
558
|
+
try:
|
|
559
|
+
result = response.json() if len(response.content) > 0 else ""
|
|
560
|
+
if isinstance(result, dict) and includeUrl:
|
|
561
|
+
result["url"] = response.url
|
|
562
|
+
return cast(Union[dict, str], result), None
|
|
563
|
+
except:
|
|
564
|
+
errors = []
|
|
565
|
+
try:
|
|
566
|
+
errors = response.text.split("\n")
|
|
567
|
+
except:
|
|
568
|
+
pass
|
|
569
|
+
errorResponse = LOGSErrorResponse()
|
|
570
|
+
errors.insert(0, "%d %s" % (response.status_code, response.reason))
|
|
571
|
+
errorResponse.errors = errors
|
|
572
|
+
else:
|
|
573
|
+
|
|
574
|
+
if response.status_code in self._noErrorStates:
|
|
575
|
+
errorResponse = LOGSErrorResponse()
|
|
576
|
+
errorResponse.status = response.status_code
|
|
577
|
+
else:
|
|
578
|
+
try:
|
|
579
|
+
r = response.json()
|
|
580
|
+
errorResponse = LOGSErrorResponse(r)
|
|
581
|
+
except:
|
|
582
|
+
errors = []
|
|
583
|
+
try:
|
|
584
|
+
errors = response.text.split("\n")
|
|
585
|
+
except:
|
|
586
|
+
pass
|
|
587
|
+
errorResponse = LOGSErrorResponse()
|
|
588
|
+
errors.insert(0, "%d %s" % (response.status_code, response.reason))
|
|
589
|
+
errorResponse.errors = errors
|
|
590
|
+
|
|
591
|
+
return (
|
|
592
|
+
response,
|
|
593
|
+
(
|
|
594
|
+
errorResponse
|
|
595
|
+
if errorResponse and errorResponse.errorStringList
|
|
596
|
+
else None
|
|
597
|
+
),
|
|
598
|
+
)
|
|
599
|
+
|
|
600
|
+
@property
|
|
601
|
+
def version(self) -> str:
|
|
602
|
+
return self._version
|
|
603
|
+
|
|
604
|
+
@property
|
|
605
|
+
def protocol(self) -> str:
|
|
606
|
+
return self._protocol
|
|
607
|
+
|
|
608
|
+
@property
|
|
609
|
+
def server(self) -> str:
|
|
610
|
+
return self._server
|
|
611
|
+
|
|
612
|
+
@property
|
|
613
|
+
def port(self) -> Optional[int]:
|
|
614
|
+
return self._port
|
|
615
|
+
|
|
616
|
+
@property
|
|
617
|
+
def group(self) -> str:
|
|
618
|
+
return self._group
|
|
619
|
+
|
|
620
|
+
@property
|
|
621
|
+
def apiUrl(self) -> str:
|
|
622
|
+
return "%s/api/%s" % (self.url, self.version)
|
|
623
|
+
|
|
624
|
+
@property
|
|
625
|
+
def url(self) -> str:
|
|
626
|
+
return "%s://%s%s/%s" % (
|
|
627
|
+
self.protocol,
|
|
628
|
+
self.server,
|
|
629
|
+
":" + str(self.port) if self.port else "",
|
|
630
|
+
self.group,
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
@url.setter
|
|
634
|
+
def url(self, value):
|
|
635
|
+
self.setUrl(value)
|
|
636
|
+
|
|
637
|
+
@property
|
|
638
|
+
def apiKey(self) -> str:
|
|
639
|
+
return self._apiKey
|
|
640
|
+
|
|
641
|
+
@apiKey.setter
|
|
642
|
+
def apiKey(self, value):
|
|
643
|
+
self._apiKey = value
|
|
644
|
+
|
|
645
|
+
@property
|
|
646
|
+
def metadata(self) -> ServerMetaData:
|
|
647
|
+
return self._metadata
|
LOGS/LOGSOptions.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class LOGSOptions:
|
|
7
|
+
showRequestUrl: bool = False
|
|
8
|
+
showRequestHeader: bool = False
|
|
9
|
+
showRequestBody: bool = False
|
|
10
|
+
showServerInfo: bool = False
|
|
11
|
+
proxyTargetUrl: Optional[str] = None
|