### Install PySNC using pip Source: https://servicenow.github.io/PySNC/index.html/user/install This command installs the PySNC library directly from PyPI using the pip package manager. It is the simplest and most common method for users to get started with PySNC. ```shell $ pip install pysnc ``` -------------------------------- ### Executing a PySNC GlideRecord Query Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows the final step of executing a GlideRecord query after all conditions have been added. No HTTP requests are made until this method is called. ```python gr.query() ``` -------------------------------- ### Initializing PySNC ServiceNowClient Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows two ways to initialize the ServiceNowClient. The first uses a secure ServiceNowPasswordGrantFlow for authentication, while the second provides a less secure direct username/password tuple. ```python client = ServiceNowClient('dev00000', ServiceNowPasswordGrantFlow('admin', password, client_id, client_secret)) # or more insecurely... client = pysnc.ServiceNowClient('dev00000', ('admin', password)) ``` -------------------------------- ### Limit and Select Fields for ServiceNow Queries Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Demonstrates how to limit the number of records returned and specify which fields to retrieve using `gr.limit` and `gr.fields`. Examples include setting a numeric limit, specifying fields as a comma-separated string or a list, and using dot-walking for related fields. It also shows how to adjust the batch size for queries. ```Python gr.limit = 5 gr.fields = 'sys_id,short_description' gr.fields = ['sys_id', 'short_description'] gr.fields = 'sys_id,assignment_group.short_description' gr = client.GlideRecord('...', batch_size=50) gr.batch_size = 60 ``` -------------------------------- ### Specifying Fields to Return (List) in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates an alternative way to specify fields to return using a Python list of field names. This achieves the same optimization as the string method. ```python gr.fields = ['sys_id', 'short_description'] ``` -------------------------------- ### Importing ServiceNowClient in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates how to import the ServiceNowClient class from the pysnc library, which is the primary interface for interacting with a ServiceNow instance. ```python from pysnc import ServiceNowClient ``` -------------------------------- ### Initializing and Setting PySNC GlideRecord Fields Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows how to initialize a new GlideRecord and then set field values using both direct assignment and the set_value() method. It also demonstrates retrieving the set value. ```python gr = client.GlideRecord('incident') gr.initialize() gr.state = 4 gr.get_value('state') gr.set_value('state', 4) ``` -------------------------------- ### Retrieve Single ServiceNow Record Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Shows how to retrieve a single record using `GlideRecord.get()`. Examples include getting a record by its `sys_id` and by a specific field like 'number'. ```Python gr.get('6816f79cc0a8016401c5a33be04be441') gr.get('number', 'PRB123456') ``` -------------------------------- ### Specifying Fields to Return (String) in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows how to specify a comma-separated string of field names to be returned by the query. This optimizes performance by reducing the data payload from the ServiceNow instance. ```python gr.fields = 'sys_id,short_description' ``` -------------------------------- ### Initialize ServiceNowClient and GlideRecord Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Demonstrates how to import `ServiceNowClient`, instantiate it with different authentication methods (secure password grant flow and insecure tuple), and then create a `GlideRecord` object to interact with a specific table like 'incident'. It also shows how to add basic queries using Pythonic naming conventions. ```Python from pysnc import ServiceNowClient client = ServiceNowClient('dev00000', ServiceNowPasswordGrantFlow('admin', password, client_id, client_secret)) # or more insecurely... client = pysnc.ServiceNowClient('dev00000', ('admin', password)) gr = client.GlideRecord('incident') gr.add_query("active", "true") gr.query() gr.add_active_query() ``` -------------------------------- ### Prepare for ServiceNow Record Insert Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Shows the initial step for inserting a new record into ServiceNow: calling `initialize()` on a `GlideRecord` object. This prepares the record for setting values before an insert operation. ```Python gr = client.GlideRecord('problem') gr.initialize() ``` -------------------------------- ### Build and install PySNC from source using Poetry Source: https://servicenow.github.io/PySNC/index.html/_sources/user/install.rst These commands demonstrate how to build the PySNC library from its source code using Poetry, then install the generated wheel file. This method is useful for developers or when a specific version not available on PyPI is required. ```Shell $ poetry install ... $ poetry build Building pysnc (1.0.7) - Building sdist - Built pysnc-1.0.7.tar.gz - Building wheel - Built pysnc-1.0.7-py3-none-any.wh $ pip install pysnc-1.0.7-py3-none-any.wh ``` -------------------------------- ### Update Existing ServiceNow Record with PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows how to retrieve an existing ServiceNow record by its sys_id using `get()` and then update its fields. After modifying the desired fields, `update()` is called to save the changes to the record. ```Python >>> gr = client.GlideRecord('problem') >>> gr.get('a06252790b6693009fde8a4b33673aed') True >>> gr.short_description = "Updated Problem" >>> gr.update() 'a06252790b6693009fde8a4b33673aed' ``` -------------------------------- ### Adding a Query and Executing in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates adding a simple query condition to a GlideRecord object and then executing the query. It highlights PySNC's adherence to Python naming conventions (e.g., add_query instead of addQuery). ```python gr.add_query("active", "true") gr.query() ``` -------------------------------- ### Getting a Single Record by Field Value in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows how to retrieve a single record by specifying a field name and its corresponding value. This allows for fetching records based on unique identifiers other than sys_id. ```python gr.get('number', 'PRB123456') ``` -------------------------------- ### Build and Install PySNC from source using Poetry Source: https://servicenow.github.io/PySNC/index.html/user/install These commands illustrate how to build the PySNC library from its source code using Poetry, followed by installing the generated wheel file. This method is suitable for developers or when a specific version not available on PyPI is required. ```shell $ poetry install ... $ poetry build Building pysnc (1.0.7) - Building sdist - Built pysnc-1.0.7.tar.gz - Building wheel - Built pysnc-1.0.7-py3-none-any.wh $ pip install pysnc-1.0.7-py3-none-any.wh ``` -------------------------------- ### Adding an Encoded Query in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows how to apply an encoded query string to a GlideRecord object, providing a powerful way to define complex query conditions. ```python gr.add_encoded_query("valuesLIKE1^active=true") ``` -------------------------------- ### Adding a Conditional Query in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates adding a query with an operator to a GlideRecord object, allowing for more complex filtering conditions similar to ServiceNow's GlideRecord API. ```python gr.add_query("value", ">", "1") ``` -------------------------------- ### Delete ServiceNow Record with PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet illustrates how to delete an existing ServiceNow record. It first retrieves the record using its sys_id with `get()` and then calls the `delete()` method to remove it from the table. ```Python >>> gr = client.GlideRecord('problem') >>> gr.get('a06252790b6693009fde8a4b33673aed') True >>> gr.delete() True ``` -------------------------------- ### Getting a Single Record by Sys ID in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates retrieving a single record from a GlideRecord object using its sys_id. The method returns True if the record is found, False otherwise. ```python gr.get('6816f79cc0a8016401c5a33be04be441') ``` -------------------------------- ### Adding OR Conditions to PySNC Queries Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates how to construct an 'OR' condition within a PySNC query. It first adds a query and then chains an 'OR' condition to it, allowing for flexible record retrieval. ```python o = gr.add_query('priority','1') o.add_or_condition('priority','2') ``` -------------------------------- ### Querying ServiceNow Records with GlideRecord Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Illustrates various methods for querying records using `GlideRecord`. This includes adding simple queries with operators, using encoded queries, and constructing 'OR' conditions. It emphasizes that HTTP requests are only made when `query()` is called. ```Python gr.add_query("value", ">", "1") gr.add_encoded_query("valuesLIKE1^active=true") o = gr.add_query('priority','1') o.add_or_condition('priority','2') gr.query() ``` -------------------------------- ### Creating a GlideRecord Object in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet illustrates how to create a GlideRecord object using the initialized ServiceNowClient. The GlideRecord object represents a table in ServiceNow, in this case, the 'incident' table. ```python gr = client.GlideRecord('incident') ``` -------------------------------- ### Adding an Active Query in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows a convenience method add_active_query() available on the GlideRecord object to quickly filter for active records, following Pythonic conventions. ```python gr.add_active_query() ``` -------------------------------- ### Setting ServiceNow Record Field Values Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Demonstrates how to set field values on a `GlideRecord` object after initializing it. It shows setting values using direct dot notation and the `set_value()` method, and then verifying the set value. ```Python gr = client.GlideRecord('incident') gr.initialize() gr.state = 4 gr.get_value('state') gr.set_value('state', 4) ``` -------------------------------- ### Getting Row Count of PySNC GlideRecord Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet illustrates how to determine the number of records in a GlideRecord object using both the Python len() function and the get_row_count() method. It shows the count before and after executing a query. ```python gr = client.GlideRecord('incident') len(gr) gr.get_row_count() gr.query() len(gr) gr.get_row_count() ``` -------------------------------- ### Install PySNC using pip Source: https://servicenow.github.io/PySNC/index.html/_sources/user/install.rst This command installs the PySNC library directly from PyPI using the pip package manager. It is the simplest and recommended method for most users. ```Shell $ pip install pysnc ``` -------------------------------- ### Iterating PySNC GlideRecord Results Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet illustrates two ways to iterate over GlideRecord results: the traditional while gr.next(): loop and the more Pythonic for r in gr: loop. The latter automatically handles rewinding. ```python while gr.next(): pass for r in gr: pass ``` -------------------------------- ### Delete a record using pysnc GlideRecord Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst This snippet illustrates how to delete a specific record from a ServiceNow table. It first retrieves the record using `get()` and then calls `delete()` to remove it. It returns `True` on successful deletion. ```python gr = client.GlideRecord('problem') gr.get('a06252790b6693009fde8a4b33673aed') gr.delete() ``` -------------------------------- ### Limiting PySNC Query Results Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates how to set a limit on the number of records returned by a GlideRecord query. This is useful for testing or managing the volume of data retrieved from the REST API. ```python gr.limit = 5 ``` -------------------------------- ### Setting Batch Size for PySNC GlideRecord Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet shows how to configure the batch size for GlideRecord queries, either during initialization or by setting the batch_size property. This affects how many records are fetched per API call. ```python gr = client.GlideRecord('...', batch_size=50) gr.batch_size = 60 ``` -------------------------------- ### Insert New ServiceNow Record with PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet demonstrates how to create and insert a new record into a ServiceNow table (e.g., 'problem') using the PySNC GlideRecord object. It requires calling `initialize()` before setting field values and then `insert()` to persist the record. ```Python >>> gr = client.GlideRecord('problem') >>> gr.initialize() >>> gr.short_description = "Example Problem" >>> gr.description = "Example Description" >>> gr.insert() 'a06252790b6693009fde8a4b33673aed' ``` -------------------------------- ### Update an existing record using pysnc GlideRecord Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst This snippet shows how to retrieve an existing record by its sys_id using `get()`, modify its fields, and then persist the changes using `update()`. It returns the sys_id of the updated record. ```python gr = client.GlideRecord('problem') gr.get('a06252790b6693009fde8a4b33673aed') gr.short_description = "Updated Problem" gr.update() ``` -------------------------------- ### Specifying Dot-Walked Fields in PySNC Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This snippet illustrates how to use dot-walking within the fields property to retrieve values from related tables directly. This reduces the need for subsequent queries to fetch related record data. ```python gr.fields = 'sys_id,assignment_group.short_description' ``` -------------------------------- ### Get Record Count (Length) in ServiceNow Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Explains how to determine the number of records in a `GlideRecord` object using both the Python `len()` function and the `get_row_count()` method, showing they yield the same result before and after a query. ```Python gr = client.GlideRecord('incident') len(gr) gr.get_row_count() gr.query() len(gr) gr.get_row_count() ``` -------------------------------- ### Iterate Through ServiceNow Records Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Explains two methods for iterating through `GlideRecord` results: the traditional `while gr.next():` loop and the more Pythonic `for r in gr:` loop. It notes that the Pythonic iteration does not require `rewind()` for multiple passes. ```Python while gr.next(): pass for r in gr: pass ``` -------------------------------- ### Insert a new record using pysnc GlideRecord Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst This snippet demonstrates how to create a new record in a ServiceNow table (e.g., 'problem') by setting field values and calling `insert()`. It returns the sys_id of the newly created record. ```python gr.short_description = "Example Problem" gr.description = "Example Description" gr.insert() ``` -------------------------------- ### Quickstart: Querying ServiceNow User Data with PySNC GlideRecord Source: https://servicenow.github.io/PySNC/index.html/index This snippet demonstrates how to initialize a PySNC ServiceNow client, perform a GlideRecord query on the 'sys_user' table for the 'admin' user, and iterate through the results to print the user's name and sys_id using a Python for-loop. It requires a ServiceNow instance URL and user credentials. ```Python >>> client = pysnc.ServiceNowClient('dev00000', ('admin', password)) >>> gr = client.GlideRecord('sys_user') >>> gr.add_query('user_name', 'admin') >>> gr.query() >>> for r in gr: ... print(f"{r.user_name}'s sys_id is {r.sys_id}") ... admin's sys_id is 6816f79cc0a8016401c5a33be04be441 ``` -------------------------------- ### PySNC Quickstart: Querying ServiceNow User Data Source: https://servicenow.github.io/PySNC/index.html/_sources/index.rst This snippet demonstrates the basic steps to connect to a ServiceNow instance using `pysnc.ServiceNowClient`, create a `GlideRecord` for the `sys_user` table, add a query to filter by `user_name`, execute the query, and then iterate through the results to print the user's name and sys_id. ```python client = pysnc.ServiceNowClient('dev00000', ('admin', password)) gr = client.GlideRecord('sys_user') gr.add_query('user_name', 'admin') gr.query() for r in gr: print(f"{r.user_name}'s sys_id is {r.sys_id}") ``` -------------------------------- ### Store and Retrieve Passwords using Keyring Source: https://servicenow.github.io/PySNC/index.html/_sources/user/authentication.rst Provides an example of using the `keyring` module to securely store and retrieve passwords. It includes functions to check for existing passwords and set new ones, demonstrating how to integrate this with command-line options for password input, ensuring credentials are not hardcoded. ```Python import keyring def check_keyring(instance, user): passw = keyring.get_password(instance, user) return passw def set_keyring(instance, user, passw): keyring.set_password(instance, user, passw) if options.password: passw = options.password set_keyring(options.instance, options.user, passw) else: passw = check_keyring(options.instance, options.user) if passw is None: print('No Password specified and none found in keyring') sys.exit(1) client = pysnc.ServiceNowClient(options.instance, ...) ``` -------------------------------- ### ServiceNowClient Class Definition and Initialization Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Defines the main client class for interacting with ServiceNow instances. The constructor handles instance URL parsing, proxy configuration, and various authentication methods including basic auth, OAuth2, and existing requests sessions, ensuring proper session setup with retries and headers. ```APIDOC class ServiceNowClient(object): """ ServiceNow Python Client :param str instance: The instance to connect to e.g. ``https://dev00000.service-now.com`` or ``dev000000`` :param auth: Username password combination ``(name,pass)`` or :class:`pysnc.ServiceNowOAuth2` or ``requests.sessions.Session`` or ``requests.auth.AuthBase`` object :param proxy: HTTP(s) proxy to use as a str ``'http://proxy:8080`` or dict ``{'http':'http://proxy:8080'}`` :param bool verify: Verify the SSL/TLS certificate OR the certificate to use. Useful if you're using a self-signed HTTPS proxy. :param cert: if String, path to ssl client cert file (.pem). If Tuple, (‘cert’, ‘key’) pair. """ def __init__(self, instance, auth, proxy=None, verify=None, cert=None, auto_retry=True): self._log = logging.getLogger(__name__) self.__instance = get_instance(instance) if proxy: if type(proxy) != dict: proxies = dict(http=proxy, https=proxy) else: proxies = proxy self.__proxies = proxies if verify is None: verify = True # default to verify with proxy else: self.__proxies = None if auth is not None and cert is not None: raise AuthenticationException('Cannot specify both auth and cert') elif isinstance(auth, (list, tuple)) and len(auth) == 2: self.__user = auth[0] auth = requests.auth.HTTPBasicAuth(auth[0], auth[1]) self.__session = requests.session() self.__session.auth = auth elif isinstance(auth, AuthBase): self.__session = requests.session() self.__session.auth = auth elif isinstance(auth, requests.sessions.Session): # maybe we've got an oauth token? Let this be permissive self.__session = auth elif isinstance(auth, ServiceNowFlow): self.__session = auth.authenticate(self.__instance, proxies=self.__proxies, verify=verify) elif cert is not None: self.__session.cert = cert else: raise AuthenticationException('No valid authentication method provided') if proxy: self.__session.proxies = self.__proxies if verify is not None: self.__session.verify = verify self.__session.headers.update(dict(Accept="application/json")) if auto_retry is True: # https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html#module-urllib3.util.retry retry = Retry(total=4, backoff_factor=0.2, status_forcelist=[429, 500, 502, 503]) self.__session.mount(self.__instance, HTTPAdapter(max_retries=retry)) self.table_api = TableAPI(self) self.attachment_api = AttachmentAPI(self) self.batch_api = BatchAPI(self) ``` -------------------------------- ### Accessing ServiceNow Record Field Values Source: https://servicenow.github.io/PySNC/index.html/_sources/user/getting_started.rst Illustrates various ways to access field values from a `GlideRecord` object. This includes direct dot notation, `get_value()`, `get_display_value()`, comparisons, f-string formatting, and checking for null values with `nil()`. It also shows how to set field values using dot notation. ```Python gr = client.GlideRecord('problem') gr.query() gr.next() gr.state gr.get_value('state') gr.get_display_value('state') gr.state == '3' f"State is {gr.state}" gr.state.nil() gr.state = '4' gr.state gr.state.get_value() ``` -------------------------------- ### Accessing and Modifying PySNC GlideRecord Fields Source: https://servicenow.github.io/PySNC/index.html/user/getting_started This comprehensive snippet demonstrates various ways to access and modify field values on a GlideRecord object. It shows direct dot notation access, get_value(), get_display_value(), comparison, f-strings, checking for null, and direct assignment. ```python gr = client.GlideRecord('problem') gr.query() gr.next() gr.state gr.get_value('state') gr.get_display_value('state') gr.state == '3' f"State is {gr.state}" gr.state.nil() gr.state = '4' gr.state gr.state.get_value() ``` -------------------------------- ### GlideElement.startswith() Method Source: https://servicenow.github.io/PySNC/index.html/api Checks if the string starts with the specified prefix. Optional 'start' and 'end' parameters can define a substring to test. The prefix can also be a tuple of strings to try. ```APIDOC GlideElement.startswith(prefix: str | tuple[str, ...], start: int = 0, end: int = None) -> bool prefix: str | tuple[str, ...] - The string or tuple of strings to check for as a prefix. start: int (default: 0) - The position in the string to begin the test. end: int (default: None) - The position in the string to end the comparison. ``` -------------------------------- ### Python: Add Query with Operator Source: https://servicenow.github.io/PySNC/index.html/api Example demonstrating how to use the `add_query` method with an operator and a second value, creating a query like `nameLIKEtest`. ```python add_query('name', 'LIKE', 'test') ``` -------------------------------- ### Configure HTTP Proxies for pysnc Client Source: https://servicenow.github.io/PySNC/index.html/_sources/user/advanced.rst Explains how to configure HTTP proxies for the pysnc ServiceNowClient. It shows examples of specifying a proxy using a URL string or a dictionary for different protocols (http/https). ```python >>> proxy_url = 'http://localhost:8080' >>> client = pysnc.ServiceNowClient(..., proxy=proxy_url) ``` ```python >>> client = pysnc.ServiceNowClient(..., proxy={'http': proxy_url, 'https': proxy_url} ``` -------------------------------- ### Storing Passwords with Python Keyring Source: https://servicenow.github.io/PySNC/index.html/user/authentication Provides an example of using the Python keyring module to securely store and retrieve passwords. This is highly recommended for managing sensitive credentials, allowing applications to access passwords without hardcoding them. ```Python import keyring def check_keyring(instance, user): passw = keyring.get_password(instance, user) return passw def set_keyring(instance, user, passw): keyring.set_password(instance, user, passw) if options.password: passw = options.password set_keyring(options.instance, options.user, passw) else: passw = check_keyring(options.instance, options.user) if passw is None: print('No Password specified and none found in keyring') sys.exit(1) client = pysnc.ServiceNowClient(options.instance, ...) ``` -------------------------------- ### PySNC API: List ServiceNow Records (GET with Filters) Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Retrieves a list of ServiceNow records based on parameters defined in the GlideRecord object. It constructs a GET request and adds it to the request queue for asynchronous processing. ```APIDOC def list(self, record: GlideRecord, hook: Callable): params = self._set_params(record) target_url = self._table_target(record.table) req = requests.Request('GET', target_url, params=params) self._add_request(req, hook) ``` -------------------------------- ### Python: Add Query for Equality Source: https://servicenow.github.io/PySNC/index.html/api Example demonstrating how to use the `add_query` method to add a simple equality condition to a record query, such as `active=true`. ```python add_query('active', 'true') ``` -------------------------------- ### Python GlideRecord: query Method Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record Executes a GET query on the table. It can raise AuthenticationException if the user lacks rights or RequestException if the transaction is canceled due to execution time. ```APIDOC query(query=None): Query the table - executes a GET :raise: :AuthenticationException: If we do not have rights :RequestException: If the transaction is canceled due to execution time ``` -------------------------------- ### Retrieve ServiceNow Record by Sys ID Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Fetches a single record from the ServiceNow instance using its system ID. This method constructs the target URL and sends a GET request to retrieve the record. ```Python def get(self, sys_id=None): target_url = self._target(sys_id) req = requests.Request('GET', target_url, params={}) return self._send(req) ``` -------------------------------- ### Perform Join Queries in pysnc Source: https://servicenow.github.io/PySNC/index.html/_sources/user/advanced.rst Demonstrates how to perform a join query using add_join_query() in pysnc, mimicking database join operations. This example joins sys_user with sys_user_group based on the manager field and filters for active records. ```python >>> gr = client.GlideRecord('sys_user') >>> join_query = gr.add_join_query('sys_user_group', join_table_field='manager') >>> join_query.add_query('active','true') >>> gr.query() ``` -------------------------------- ### Traditional Iteration of ServiceNow GlideRecord Results with PySNC Source: https://servicenow.github.io/PySNC/index.html/index This example illustrates an alternative, more traditional method for iterating through GlideRecord query results in PySNC. It uses a `while gr.next():` loop to advance through records and retrieve the 'sys_id' of each record using `gr.get_value()`, printing it to the console. ```Python >>> while gr.next(): ... print(gr.get_value('sys_id')) ... 6816f79cc0a8016401c5a33be04be441 ``` -------------------------------- ### GlideRecord.query - Execute Table Query Source: https://servicenow.github.io/PySNC/index.html/api Executes a GET query on the table. This method can raise exceptions if the user lacks sufficient rights or if other request-related failures occur. ```APIDOC GlideRecord.query(query=None) Description: Query the table - executes a GET Raises: AuthenticationException: If we do not have rights RequestException: ``` -------------------------------- ### List Attachments in ServiceNow Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Lists attachments based on the provided Attachment object. This method sets the necessary parameters from the attachment object and sends a GET request to the ServiceNow API, requesting a JSON response. ```Python def list(self, attachment: Attachment): params = self._set_params(attachment) url = self._target() req = requests.Request('GET', url, params=params, headers=dict(Accept="application/json")) return self._send(req) ``` -------------------------------- ### Download File from ServiceNow by Sys ID Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Downloads a file associated with a given system ID from ServiceNow. It is highly recommended to use a 'with' statement (e.g., 'with api.get_file(sys_id) as f:') to ensure proper handling and closure of the file stream, as leaving it unread could result in open handles. Sends a GET request to the file endpoint. ```Python def get_file(self, sys_id, stream=True): """ This may be dangerous, as stream is true and if not fully read could leave open handles One should always ``with api.get_file(sys_id) as f:`` """ target_url = "{}/file".format(self._target(sys_id)) req = requests.Request('GET', target_url) return self._send(req, stream=stream) ``` -------------------------------- ### PySNC API Overview Source: https://servicenow.github.io/PySNC/index.html/index This section outlines the main components and classes available in the PySNC API for interacting with ServiceNow. It lists core classes like ServiceNowClient and GlideRecord, along with other modules for attachments, general APIs, and exception handling. ```APIDOC The ServiceNowClient GlideRecord Attachment APIs Exceptions (module pysnc.exceptions) ``` -------------------------------- ### ServiceNowClient Class API Reference Source: https://servicenow.github.io/PySNC/index.html/api Detailed API documentation for the pysnc.ServiceNowClient class, which serves as the primary interface for connecting to and interacting with ServiceNow instances. It outlines the constructor parameters for instance connection and authentication, along with methods for creating Attachment and GlideRecord objects, and properties for accessing instance details and the underlying requests session. ```APIDOC class pysnc.ServiceNowClient(instance, auth, proxy=None, verify=None, cert=None, auto_retry=True) Description: ServiceNow Python Client Parameters: instance (str): The instance to connect to e.g. `https://dev00000.service-now.com` or `dev000000` auth: Username password combination `(name,pass)` or `pysnc.ServiceNowOAuth2` or `requests.sessions.Session` or `requests.auth.AuthBase` object proxy: HTTP(s) proxy to use as a str `'http://proxy:8080` or dict `{'http':'http://proxy:8080'}` verify (bool): Verify the SSL/TLS certificate OR the certificate to use. Useful if you’re using a self-signed HTTPS proxy. cert: if String, path to ssl client cert file (.pem). If Tuple, (‘cert’, ‘key’) pair. Methods: Attachment(table) -> pysnc.Attachment Description: Create an Attachment object for the current client Returns: pysnc.Attachment GlideRecord(table, batch_size=100, rewindable=True) -> pysnc.GlideRecord Description: Create a `pysnc.GlideRecord` for a given table against the current client Parameters: table (str): The table name e.g. `problem` batch_size (int): Batch size (items returned per HTTP request). Default is `100`. rewindable (bool): If we can rewind the record. Default is `True`. If `False` then we cannot rewind the record, which means as an Iterable this object will be ‘spent’ after iteration. This is normally the default behavior expected for a python Iterable, but not a GlideRecord. When `False` less memory will be consumed, as each previous record will be collected. Returns: pysnc.GlideRecord static guess_is_sys_id(value) -> bool Description: Attempt to guess if this is a probable sys_id Parameters: value (str): the value to check Returns: If this is probably a sys_id Return type: bool Properties: instance: str Description: The instance we’re associated with. Returns: Instance URI Return type: str session Description: The requests session Returns: The requests session ``` -------------------------------- ### API Documentation for add_query Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record API documentation for the `add_query` method. ```APIDOC add_query(self, name: str, value: str, second_value: Optional[str] = None) -> QueryCondition Description: Add a query to a record. Parameters: name (str): Table field name. value (str): Either the value for an equality check or an operator if `second_value` is specified. Number Operators: =, !=, >, >=, <, <= String Operators: =, !=, IN, NOT IN, STARTSWITH, ENDSWITH, CONTAINS, DOES NOT CONTAIN, INSTANCEOF second_value (str, optional): If specified, `value` is expected to be an operator. Returns: A QueryCondition object. ``` -------------------------------- ### API Documentation for add_join_query Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record API documentation for the `add_join_query` method. ```APIDOC add_join_query(self, join_table: str, primary_field: Optional[str] = None, join_table_field: Optional[str] = None) -> JoinQuery Description: Do a join query. Parameters: join_table (str): The table to join against. primary_field (str, optional): The current table field to use for the join. Defaults to `sys_id`. join_table_field (str, optional): The `join_Table` field to use for the join. Returns: A :class:`query.JoinQuery` object. Example: gr = client.GlideRecord('sys_user') join_query = gr.add_join_query('sys_user_group', join_table_field='manager') join_query.add_query('active','true') gr.query() ``` -------------------------------- ### GlideRecord.set_new_guid_value() Method Source: https://servicenow.github.io/PySNC/index.html/api Sets a new GUID value for the record. This method assumes the GUID is a sys_id; otherwise, the value should be set directly. ```APIDOC GlideRecord.set_new_guid_value(value) Description: This does make an assumption the guid is a sys_id, if it is not, set the value directly. Parameters: value: A 32 byte string that is the value ``` -------------------------------- ### Basic Authentication with pysnc Source: https://servicenow.github.io/PySNC/index.html/user/authentication Demonstrates how to use basic authentication with pysnc, providing the username and password directly. This method is simple but insecure and not recommended for production or machine-to-machine activity. ```Python >>> client = pysnc.ServiceNowClient('dev00000', ('admin','password')) ``` -------------------------------- ### API Documentation for add_rl_query Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record API documentation for the `add_rl_query` method. ```APIDOC add_rl_query(self, related_table: str, related_field: str, operator_condition: str, stop_at_relationship: bool = False) Description: Generates a 'Related List Query' (RLQUERY). Parameters: related_table (str): The table with the relationship (the other table). related_field (str): The field in the related table to query against. operator_condition (str): The operator and value for the condition (e.g., `=0`, `>0`). stop_at_relationship (bool, optional): If True, allows dot-walking the related field (e.g., `role.name`). RLQUERY Format: RLQUERY.,[,m2m][^subquery]^ENDRLQUERY Examples: - Find active users with no manager (LEFT OUTER JOIN simulation): RLQUERYsys_user.manager,=0^active=true^ENDRLQUERY - Find users with a specific role: RLQUERYsys_user_has_role.user,>0^role=ROLESYSID^ENDRLQUERY - Dot-walk the role (stop_at_relationship=True): RLQUERYsys_user_has_role.user,>0,m2m^role.name=admin^ENDRLQUERY ``` -------------------------------- ### PySNC API: Retrieve a ServiceNow Record (GET) Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Retrieves a single ServiceNow record by its sys_id. It constructs a GET request, sets parameters, and adds the request to an internal queue with a provided hook for asynchronous processing. ```APIDOC def get(self, record: GlideRecord, sys_id: str, hook: Callable) -> None: params = self._set_params(record) if 'sysparm_offset' in params: del params['sysparm_offset'] target_url = self._table_target(record.table, sys_id) req = requests.Request('GET', target_url, params=params) self._add_request(req, hook) ``` -------------------------------- ### Configure HTTP Proxies for ServiceNowClient Source: https://servicenow.github.io/PySNC/index.html/user/advanced Explains how to configure HTTP proxies for pysnc.ServiceNowClient by providing either a URL string or a dictionary of proxy URLs for HTTP and HTTPS. ```python proxy_url = 'http://localhost:8080' client = pysnc.ServiceNowClient(..., proxy=proxy_url) client = pysnc.ServiceNowClient(..., proxy={'http': proxy_url, 'https': proxy_url} ``` -------------------------------- ### API Documentation for get_link_list Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record API documentation for the `get_link_list` method. ```APIDOC get_link_list(self) -> Optional[str] Description: Generate a full URL to for the current query. Returns: The full URL to the record query (str) ``` -------------------------------- ### Python GlideRecord: set_new_guid_value Method Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record Sets a new GUID (Globally Unique Identifier) value for the record. This method assumes the GUID is a sys_id and requires a 32-byte string value. If it's not a sys_id, the value should be set directly. ```APIDOC set_new_guid_value(value): This does make an assumption the guid is a sys_id, if it is not, set the value directly. :param value: A 32 byte string that is the value ``` -------------------------------- ### GlideRecord.get_unique_name - Get Sys_ID Source: https://servicenow.github.io/PySNC/index.html/api Returns the sys_id of the current record, which serves as its unique identifier. ```APIDOC GlideRecord.get_unique_name() → str Description: always give us the sys_id ``` -------------------------------- ### pysnc.GlideRecord.batch_size property Source: https://servicenow.github.io/PySNC/index.html/api Retrieves the configured number of records to be fetched in a single HTTP GET request when querying ServiceNow. ```APIDOC batch_size: int Description: The number of records to query in a single HTTP GET ``` -------------------------------- ### API Documentation for add_active_query Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/record API documentation for the `add_active_query` method. ```APIDOC add_active_query(self) -> QueryCondition Description: Equivalent to adding 'active=true' to the query. Returns: A QueryCondition object. ``` -------------------------------- ### Perform Dot Walking by Specifying Fields Source: https://servicenow.github.io/PySNC/index.html/user/advanced Shows how to mimic GlideRecord's dot-walking behavior by explicitly defining desired fields (e.g., opened_by.email) before querying, then retrieving values using get_value() or get_display_value(). ```python gr.fields = 'sys_id,opened_by,opened_by.email,opened_by.department.dept_head' gr.query() gr.next() gr.get_value('opened_by.email') gr.get_value('opened_by.department.dept_head') gr.get_display_value('opened_by.department.dept_head') ``` -------------------------------- ### Get Value of GlideElement Field Source: https://servicenow.github.io/PySNC/index.html/api Retrieves the current value of the `GlideElement` field. This method returns the raw value, which can be of any type. ```APIDOC get_value() -> Any Parameters: None Returns: Any - The value of the field. ``` -------------------------------- ### GlideElement.title() Method Source: https://servicenow.github.io/PySNC/index.html/api Returns a titlecased version of the string, where each word starts with an uppercased character and all remaining cased characters are lowercase. ```APIDOC GlideElement.title() -> str ``` -------------------------------- ### GlideRecord.get_row_count - Get Total Row Count Source: https://servicenow.github.io/PySNC/index.html/api A Glide compatible method that returns the total number of rows in the current record set. ```APIDOC GlideRecord.get_row_count() → int Description: Glide compatable method. Returns: int: the total ``` -------------------------------- ### Basic Authentication with pysnc Source: https://servicenow.github.io/PySNC/index.html/_sources/user/authentication.rst Demonstrates standard BasicAuth using a username and password for authentication. This method is simple but insecure and not recommended for production or machine-to-machine activity. If used, ACLs should be scoped to the minimum necessary permissions. ```Python >>> client = pysnc.ServiceNowClient('dev00000', ('admin','password')) ``` -------------------------------- ### PySNC: Get Total Record Count Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/attachment Implements the `len()` operator, returning the total number of records available, typically after a query. ```python def __len__(self): return self.__total if self.__total else 0 ``` -------------------------------- ### Python Imports for pysnc.client Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client Imports necessary modules and classes for the ServiceNow client, including HTTP request handling, logging, and internal pysnc components like exceptions, GlideRecord, Attachment, and authentication utilities. ```python from io import BytesIO import requests from requests.auth import AuthBase import re import logging import base64 from typing import Callable, no_type_check from requests.cookies import MockRequest, MockResponse from requests.structures import CaseInsensitiveDict from requests.utils import get_encoding_from_headers from requests.adapters import HTTPAdapter, Retry from .exceptions import * from .record import GlideRecord from .attachment import Attachment from .utils import get_instance, MockHeaders from .auth import ServiceNowFlow ``` -------------------------------- ### Base API Class for ServiceNow Interactions (APIDOC) Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/client The `API` class provides foundational methods and properties for interacting with the ServiceNow API. It manages the client session, sets common request parameters, validates HTTP responses, and handles sending prepared requests, including OAuth token refresh logic. ```APIDOC class API(object): __init__(self, client): client: The client object providing the session for API interactions. @property session: Returns: The client's session object. _set_params(self, record=None): record: GlideRecord object (optional). If provided, its parameters are used. Defaults to None. Returns: dict of parameters, ensuring 'sysparm_display_value' is 'all', 'sysparm_exclude_reference_link' is 'true', and 'sysparm_suppress_pagination_header' is 'true'. _validate_response(self, response: requests.Response) -> None: response: The requests.Response object to validate. Raises: NotFoundException (404): RoleException (403): AuthenticationException (401): RequestException (other 4xx/5xx codes or JSON decode errors). _send(self, req, stream=False) -> requests.Response: req: The requests.Request object to be sent. stream: Boolean, whether to stream the response content (defaults to False). Returns: The requests.Response object. Handles: OAuth token refresh if the session has a token and it's expired, by calling session.refresh_token(). ``` -------------------------------- ### PySNC: Get Current Attachment Link Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/attachment Constructs and returns the direct file URL for the current attachment if a record is active. Returns None otherwise. ```python def get_link(self) -> Optional[str]: if self._current(): return f"{self._client.instance}/api/now/v1/attachment/{self.sys_id}/file" return None ``` -------------------------------- ### APIDOC: pysnc.GlideElement.rsplit method Source: https://servicenow.github.io/PySNC/index.html/api Splits the string into a list of substrings using a separator, starting from the end of the string. Supports optional separator and maxsplit arguments. ```APIDOC Method: rsplit(*sep=None*, *maxsplit=-1*) Description: Return a list of the substrings in the string, using sep as the separator string. Splitting starts at the end of the string and works to the front. Parameters: sep: (Optional) The separator used to split the string. When set to None (default), splits on any whitespace character (including newline, carriage return, tab, form feed, and spaces) and discards empty strings from the result. maxsplit: (Optional) Maximum number of splits. -1 (default) means no limit. Returns: list: A list of substrings. ``` -------------------------------- ### pysnc.Attachment Class API Reference Source: https://servicenow.github.io/PySNC/index.html/api Detailed API documentation for the `pysnc.Attachment` class, outlining its constructor, methods, parameters, return types, and exceptions. ```APIDOC class pysnc.Attachment(client, table) __init__(client, table) client: The ServiceNow client instance. table: The table name associated with the attachment. add_query(name, value, second_value=None) -> QueryCondition Add a query to a record. Parameters: name (str): Table field name. value (str): Either the value in which `name` must be = to else an operator if `second_value` is specified. Numbers: =, !=, >, >=, <, <= Strings: =, !=, IN, NOT IN, STARTSWITH, ENDSWITH, CONTAINS, DOES NOT CONTAIN, INSTANCEOF second_value (str, optional): If specified then `value` is expected to be an operator. as_temp_file(chunk_size: int = 512) -> SpooledTemporaryFile Return the attachment as a TempFile. Parameters: chunk_size (int): Bytes to read in at a time from the HTTP stream. Returns: SpooledTemporaryFile get(sys_id: str) -> bool Get a single record. If one value is passed, assumed to be sys_id. If two values are passed in, the first value is the column name to be used. Can return multiple records. Parameters: sys_id (str): The ID of the attachment. Returns: True or False based on success. next(_recursive=False) -> bool Returns the next record in the record set. Returns: True or False based on success. query() -> void Query the table. Returns: void Raises: AuthenticationException: If we do not have rights. RequestException: If the transaction is canceled due to execution time. read() -> bytes Read the entire attachment. Returns: b'' readlines(encoding='UTF-8', delimiter='\n') -> List[str] Read the attachment, as text, decoding by default as UTF-8, splitting by the delimiter. Parameters: encoding (str): Encoding to use, defaults to UTF-8. delimiter (str): What to split by, default is newline. Returns: list write_to(path, chunk_size=512) -> Path Write the attachment to the given path - if the path is a directory the file_name will be used. ``` -------------------------------- ### PySNC: Add Query Condition Source: https://servicenow.github.io/PySNC/index.html/_modules/pysnc/attachment Adds a query condition to the record. Supports various operators for numbers and strings. Examples demonstrate how to create simple and complex queries. ```APIDOC def add_query(self, name, value, second_value=None) -> QueryCondition: """ Add a query to a record. For example:: add_query('active', 'true') Which will create the query ``active=true``. If we specify the second_value:: add_query('name', 'LIKE', 'test') Which will create the query ``nameLIKEtest`` :param str name: Table field name :param str value: Either the value in which ``name`` must be `=` to else an operator if ``second_value`` is specified Numbers:: * = * != * > * >= * < * <= Strings:: * = * != * IN * NOT IN * STARTSWITH * ENDSWITH * CONTAINS * DOES NOT CONTAIN * INSTANCEOF :param str second_value: optional, if specified then ``value`` is expected to be an operator """ ```