sfq 0.0.30__py3-none-any.whl → 0.0.32__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.
sfq/__init__.py CHANGED
@@ -10,6 +10,7 @@ import os
10
10
  import re
11
11
  import time
12
12
  import warnings
13
+ import webbrowser
13
14
  import xml.etree.ElementTree as ET
14
15
  from collections import OrderedDict
15
16
  from concurrent.futures import ThreadPoolExecutor, as_completed
@@ -99,7 +100,7 @@ class SFAuth:
99
100
  access_token: Optional[str] = None,
100
101
  token_expiration_time: Optional[float] = None,
101
102
  token_lifetime: int = 15 * 60,
102
- user_agent: str = "sfq/0.0.30",
103
+ user_agent: str = "sfq/0.0.32",
103
104
  sforce_client: str = "_auto",
104
105
  proxy: str = "_auto",
105
106
  ) -> None:
@@ -169,6 +170,16 @@ class SFAuth:
169
170
  * 📖 [Salesforce OAuth Flows Documentation](https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_flows.htm&type=5)
170
171
  """
171
172
 
173
+ self.__version__ = "0.0.32"
174
+ """
175
+ ### `__version__`
176
+
177
+ **The version of the sfq library.**
178
+ - Schema: `MAJOR.MINOR.PATCH`
179
+ - Used for debugging and compatibility checks
180
+ - Updated to reflect the current library version via CI/CD automation
181
+ """
182
+
172
183
  self.api_version = api_version
173
184
  """
174
185
 
@@ -997,9 +1008,10 @@ class SFAuth:
997
1008
 
998
1009
  return combined_response or None
999
1010
 
1000
- def _gen_soap_envelope(self, header: str, body: str) -> str:
1001
- """Generates a full SOAP envelope with all required namespaces for Salesforce Enterprise API."""
1002
- return (
1011
+ def _gen_soap_envelope(self, header: str, body: str, type: str) -> str:
1012
+ """Generates a full SOAP envelope with all required namespaces for Salesforce API."""
1013
+ if type == "enterprise":
1014
+ return (
1003
1015
  '<?xml version="1.0" encoding="UTF-8"?>'
1004
1016
  "<soapenv:Envelope "
1005
1017
  'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" '
@@ -1010,8 +1022,24 @@ class SFAuth:
1010
1022
  f"{header}{body}"
1011
1023
  "</soapenv:Envelope>"
1012
1024
  )
1025
+ elif type == "tooling":
1026
+ return (
1027
+ '<?xml version="1.0" encoding="UTF-8"?>'
1028
+ "<soapenv:Envelope "
1029
+ 'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" '
1030
+ 'xmlns:xsd="http://www.w3.org/2001/XMLSchema" '
1031
+ 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
1032
+ 'xmlns="urn:tooling.soap.sforce.com" '
1033
+ 'xmlns:mns="urn:metadata.tooling.soap.sforce.com" '
1034
+ 'xmlns:sf="urn:sobject.tooling.soap.sforce.com">'
1035
+ f"{header}{body}"
1036
+ "</soapenv:Envelope>"
1037
+ )
1038
+ raise ValueError(
1039
+ f"Unsupported API type: {type}. Must be 'enterprise' or 'tooling'."
1040
+ )
1013
1041
 
1014
- def _gen_soap_header(self):
1042
+ def _gen_soap_header(self) -> str:
1015
1043
  """This function generates the header for the SOAP request."""
1016
1044
  headers = self._get_common_headers()
1017
1045
  session_id = headers["Authorization"].split(" ")[1]
@@ -1099,7 +1127,7 @@ class SFAuth:
1099
1127
  insert_list: List[Dict[str, Any]],
1100
1128
  batch_size: int = 200,
1101
1129
  max_workers: int = None,
1102
- api_type: Literal["enterprise", "tooling", "metadata"] = "enterprise",
1130
+ api_type: Literal["enterprise", "tooling"] = "enterprise",
1103
1131
  ) -> Optional[Dict[str, Any]]:
1104
1132
  """
1105
1133
  Execute the Insert API to insert multiple records via SOAP calls.
@@ -1116,14 +1144,13 @@ class SFAuth:
1116
1144
  endpoint += f"c/{self.api_version}"
1117
1145
  elif api_type == "tooling":
1118
1146
  endpoint += f"T/{self.api_version}"
1119
- elif api_type == "metadata":
1120
- endpoint += f"m/{self.api_version}"
1121
1147
  else:
1122
1148
  logger.error(
1123
- "Invalid API type: %s. Must be one of: 'enterprise', 'tooling', 'metadata'.",
1149
+ "Invalid API type: %s. Must be one of: 'enterprise', 'tooling'.",
1124
1150
  api_type,
1125
1151
  )
1126
1152
  return None
1153
+ endpoint = endpoint.replace('/v', '/') # handle API versioning in the endpoint
1127
1154
 
1128
1155
  if isinstance(insert_list, dict):
1129
1156
  insert_list = [insert_list]
@@ -1136,7 +1163,7 @@ class SFAuth:
1136
1163
  def insert_chunk(chunk: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
1137
1164
  header = self._gen_soap_header()
1138
1165
  body = self._gen_soap_body(sobject=sobject, method="create", data=chunk)
1139
- envelope = self._gen_soap_envelope(header, body)
1166
+ envelope = self._gen_soap_envelope(header=header, body=body, type=api_type)
1140
1167
  soap_headers = self._get_common_headers().copy()
1141
1168
  soap_headers["Content-Type"] = "text/xml; charset=UTF-8"
1142
1169
  soap_headers["SOAPAction"] = '""'
@@ -1197,4 +1224,14 @@ class SFAuth:
1197
1224
  Perform cleanup operations for Apex debug logs.
1198
1225
  """
1199
1226
  if apex_logs:
1200
- self._debug_cleanup_apex_logs()
1227
+ self._debug_cleanup_apex_logs()
1228
+
1229
+ def open_frontdoor(self) -> None:
1230
+ """
1231
+ This function opens the Salesforce Frontdoor URL in the default web browser.
1232
+ """
1233
+ if not self.access_token:
1234
+ self._get_common_headers()
1235
+ sid = quote(self.access_token, safe="")
1236
+ frontdoor_url = f"{self.instance_url}/secur/frontdoor.jsp?sid={sid}"
1237
+ webbrowser.open(frontdoor_url)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sfq
3
- Version: 0.0.30
3
+ Version: 0.0.32
4
4
  Summary: Python wrapper for the Salesforce's Query API.
5
5
  Author-email: David Moruzzi <sfq.pypi@dmoruzi.com>
6
6
  Keywords: salesforce,salesforce query
@@ -0,0 +1,6 @@
1
+ sfq/__init__.py,sha256=sGL_DT0w4-9GqmTD_rffZ_J3eqOtjFUuH1S4nlVzow8,47102
2
+ sfq/_cometd.py,sha256=XimQEubmJwUmbWe85TxH_cuhGvWVuiHHrVr41tguuiI,10508
3
+ sfq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ sfq-0.0.32.dist-info/METADATA,sha256=Y3avdu7TKc8BCEz2kHZaqjPAIqcjD4CHzSF_WdMO4pI,6899
5
+ sfq-0.0.32.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ sfq-0.0.32.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- sfq/__init__.py,sha256=MpqXIfKQW1XRGBAh_uYBpdF5tj2Mxdzf3cCNO77yyd0,45630
2
- sfq/_cometd.py,sha256=XimQEubmJwUmbWe85TxH_cuhGvWVuiHHrVr41tguuiI,10508
3
- sfq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- sfq-0.0.30.dist-info/METADATA,sha256=ieHDwbhGy16xT_kAIEWVnQIWxVHnMN1vxenlIrHypas,6899
5
- sfq-0.0.30.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- sfq-0.0.30.dist-info/RECORD,,
File without changes