### Enabling Resource Caching for Swimlane Client (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Illustrates how to enable automatic resource caching by setting the `resource_cache_size` parameter during client initialization. This example also includes basic logging setup to observe cache hits and misses. ```python # Enable basic logging to print requests and cache hits/misses import logging; logging.basicConfig(level=logging.DEBUG) from swimlane import Swimlane # Enable caching up to 20 different instances of each supported resource type swimlane = Swimlane( '192.168.1.1', 'username', 'password', resource_cache_size=20 ) # Slow code making multiple requests for the same App, Record, and referenced Records in a loop # With caching enabled, performance is much higher as requests are sent only for resources not already in the cache for _ in range(5): pass # Placeholder for loop body ``` -------------------------------- ### Adding and Removing References - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates how to get a target record from another app and use the `add` and `remove` methods on the Reference field to manage references. Shows that adding the same record multiple times is ignored. ```python other_app = swimlane.apps.get(name='Reference App') ref_target_record = other_app.records.get(id='58e24e8607637a0b488849d4') # Records added multiple times are ignored record['Reference'].add(ref_target_record) assert len(record['Reference']) == 4 record['Reference'].add(ref_target_record) assert len(record['Reference']) == 4 # Remove reference. Raises exception if not already referenced record['Reference'].remove(ref_target_record) assert len(record['Reference']) == 3 ``` -------------------------------- ### Install Swimlane Python Driver via Git Source: https://github.com/swimlane/swimlane-python/blob/master/docs/index.rst Demonstrates how to clone the repository, checkout a specific branch/release, and install the driver directly from the source code using pip. This method is intended for driver development. ```Shell git clone https://github.com/swimlane/swimlane-python cd swimlane-python git checkout pip install . ``` -------------------------------- ### Install Swimlane Python Driver Offline Source: https://github.com/swimlane/swimlane-python/blob/master/docs/index.rst Shows how to download and run the self-extracting .pyz installer for offline installation. Requires downloading the correct file from GitHub releases. ```Shell wget https://github.com/swimlane/swimlane-python/releases/download//swimlane-python--offline-installer--.pyz python ./swimlane-python--offline-installer--.pyz ``` -------------------------------- ### Install Swimlane Python Driver via pip Source: https://github.com/swimlane/swimlane-python/blob/master/README.rst Installs the Swimlane Python driver from the public PyPI repository using pip. ```Shell pip install swimlane ``` -------------------------------- ### Initializing Swimlane Client with Credentials (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates the minimal setup to connect to a Swimlane server using a host address, username, and password. Authentication is performed immediately upon instantiation. ```python from swimlane import Swimlane swimlane = Swimlane('192.168.1.1', 'username', 'password') ``` -------------------------------- ### Install Swimlane Python Driver via Pip Source: https://github.com/swimlane/swimlane-python/blob/master/docs/index.rst Provides the command to install or upgrade the Swimlane Python driver using pip. This is the recommended installation method. ```Shell pip install -U swimlane ``` -------------------------------- ### Retrieving a Single App (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates how to retrieve a single application resource using the `swimlane.apps.get()` method, providing examples for retrieval by the app's unique ID and by its name. ```python app_by_id = swimlane.apps.get(id='58f...387') app_by_name = swimlane.apps.get(name='Target App') ``` -------------------------------- ### Retrieving App Revisions - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to access historical revisions of an application using the `app.revisions` adapter. Examples include getting all revisions, getting a specific revision by number, and accessing the historical application version from a revision object. ```python # get all revisions app_revisions = app.revisions.get_all() # get by revision number app_revision = app.revisions.get(2) # get the historical version of the app historical_app_version = app_revision.version ``` -------------------------------- ### Install Functional Test Dependencies Source: https://github.com/swimlane/swimlane-python/blob/master/README.rst Installs the required Python packages for running the functional tests using the requirements.txt file. ```Shell pip install -r requirements.txt ``` -------------------------------- ### Uploading Attachment from File Handle - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Provides an example of adding a new attachment to a record by opening a file from disk in binary read mode ('rb') and passing the file handle to the `add` method. ```python # Read file from disk and add as new attachment with open('/path/to/file', 'rb') as file_handle: record['Attachment'].add('filename.txt', file_handle) ``` -------------------------------- ### Retrieving a Single User (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates how to retrieve a single user resource using the `swimlane.users.get()` method, providing examples for retrieval by the user's unique ID and by their display name. ```python user_by_id = swimlane.users.get(id='58f...387') user_by_display_name = swimlane.users.get(display_name='admin') ``` -------------------------------- ### Setting User Field with User Instance - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how to assign a User instance (specifically the current user from `swimlane.user`) to a User field and assert that the assignment was successful. ```python assert isinstance(swimlane.user, User) record['User'] = swimlane.user assert record['User'] == swimlane.user ``` -------------------------------- ### Install Swimlane Python Driver Offline Source: https://github.com/swimlane/swimlane-python/blob/master/README.rst Executes the offline installer script for the Swimlane Python driver, using a bundled dependency package. ```Shell python swimlane-python-offline-installer--.pyz ``` -------------------------------- ### Setting Text List Field Values - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates how to directly assign a new list of values to a Text List field. ```python record['Text List Field'] = ['new', 'values'] ``` -------------------------------- ### Searching Swimlane Records with Operator Constants - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates using predefined constants from `swimlane.core.search` for filter operators instead of string literals. This improves code readability and reduces potential errors. Shows examples using `EQ` and `GTE`. Requires importing the necessary constants and an app instance. ```python from swimlane.core.search import EQ, NOT_EQ, CONTAINS, EXCLUDES, GT, LT, GTE, LTE records = app.records.search( ('Text Field', EQ, 'equal value'), ('Number Field', GTE, 0), ) ``` -------------------------------- ### Accessing History Field (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how to access the read-only 'History' field, which provides a `RevisionCursor`. Demonstrates getting the total number of revisions and iterating backwards through them, accessing properties like modified date, user, revision number, and the full record version for each revision. ```python history = record['History'] assert isinstance(history, RevisionCursor) # Get number of revisions num_revisions = len(history) # Iterate backwards over revisions for idx, revision in enumerate(history): assert isinstance(revision, Revision) assert isinstance(revision.modified_date, datetime) assert isinstance(revision.user, UserGroup) assert num_revisions - revision.revision_number == idx # revision.version is a full Record instance, and fields can be accessed like a normal Record assert revision.version.id == record.id ``` -------------------------------- ### Uploading Request Response as Attachment - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates fetching data from a URL using the `requests` library, wrapping the response content in a BytesIO object, and adding it as an attachment to the record before saving. ```python from io import BytesIO import requests response = requests.get('http://httpbin.org/json') record['Attachment'].add('example.json', BytesIO(response.content)) record.save() ``` -------------------------------- ### Using Single Select ValuesListField in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Documentation and examples for the Single Select mode of the ValuesListField, which enforces valid selection options. Values are accessed and set directly. The code demonstrates setting a valid option and handling `ValidationError` when attempting to set an invalid option. ```python # Valid option enforcement record['Status'] = 'Open' try: record['Status'] = 'Not a valid option' except ValidationError: record['Status'] = 'Closed' assert record['Status'] == 'Closed' ``` -------------------------------- ### Using Multi Select ValuesListField Cursor in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Documentation and examples for the Multi Select mode of the ValuesListField, which uses a cursor similar to a standard list for selection and validation. The code demonstrates accessing the cursor, checking length, selecting/deselecting options, handling errors for invalid operations, and showing that selecting duplicates is ignored. ```python # Uses cursor for multi-select support with support for select, deselect, iteration, etc. vl_cursor = record['Values List'] assert len(vl_cursor) == 2 # Adding the same value multiple times is ignored vl_cursor.select('Option 3') assert len(vl_cursor) == 3 vl_cursor.select('Option 3') assert len(vl_cursor) == 3 # Remove element raises exception if not already added vl_cursor.deselect('Option 3') assert len(vl_cursor) == 2 try: vl_cursor.deselect('Option 3') except KeyError: assert len(vl_cursor) == 2 # Respects field's valid options and types, raising ValidationError for invalid values try: vl_cursor.select('Not a valid option') except ValidationError: assert len(vl_cursor) == 2 ``` -------------------------------- ### Using Python Date Field Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Documentation and examples for the Date field type, which returns `pendulum.Date` instances. The code demonstrates accessing the field, asserting its type, and setting the value using both full datetimes and date-only instances, showing that the time portion is dropped. ```python date_field = record['Date'] assert isinstance(date_field, datetime.date) assert isinstance(date_field, pendulum.Date) # Set to full datetime, time portion is dropped and Date instance is always returned record['Date'] = pendulum.now() assert isinstance(record['Date'], pendulum.Date) # Set to just date record['Date'] = pendulum.now().date() assert isinstance(record['Date'], pendulum.Date) ``` -------------------------------- ### Uploading Attachment from BytesIO - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how to add an attachment using data already loaded into a BytesIO object, which is useful when the file data is already in memory or needs to be used multiple times. ```python # Create new attachment from data already loaded into a file-like object # Useful when attaching data already read from disk or when that file data is used multiple times from io import BytesIO with open('/path/to/file', 'rb') as file_handle: data = file_handle.read() record['Attachment'].add('filename.txt', BytesIO(data)) ``` -------------------------------- ### Using ListField Cursor Operations in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Documentation and examples for the ListField (Text or Numeric), which uses a cursor behaving like a standard Python list but with added validation. The code demonstrates common list operations like iteration, modification, indexing, containment checks, and type validation, showing how validation errors are handled. ```python # Cursor behaving like a list text_list_cursor = record['Text List Field'] # Iteration for value in text_list_cursor: print(value) # Modification text_list_cursor.reverse() text_list_cursor.insert(0, 'new value') # Index/slice assert text_list_cursor[0] == 'new value' # Contains assert 'new value' in text_list_cursor # Type validation # Failing validation will not modify the field value original_values = list(text_list_cursor) try: text_list_cursor.append(123) except ValidationError: assert len(original_values) == len(text_list_cursor) ``` -------------------------------- ### Iterating and Downloading Attachments - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Explains how to access the Attachment field cursor, iterate through Attachment instances, assert their properties (filename, file_id, upload_date), and download the file content as a BytesIO stream. ```python attachments = record['Attachment'] assert isinstance(attachments, AttachmentCursor) for attachment in attachments: # Yields Attachment instances assert isinstance(attachment, Attachment) assert attachment.filename == '5f09afe50064b2bd718e77818b565df1.pcap' assert attachment.file_id == '58ebb22907637a0b488b7b17' assert isinstance(attachment.upload_date, datetime) # Retrieve file bytes as BytesIO stream (file-like object) stream = attachment.download() assert isinstance(stream, BytesIO) content = stream.read() assert len(content) > 0 ``` -------------------------------- ### Connecting via Non-Standard Port with Swimlane Client (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to connect to a Swimlane server running on a non-standard port by including the port number in the host URL. This example also demonstrates disabling SSL verification. ```python from swimlane import Swimlane swimlane = Swimlane( 'https://192.168.1.1:8443', 'username', 'password', verify_ssl=False ) ``` -------------------------------- ### Using Python Timespan Field Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Documentation and examples for the Timespan field type, representing a time period. It returns `pendulum.Duration` instances. The code demonstrates accessing the field and asserting its type. This field type requires `datetime.timedelta` or `pendulum.Duration` instances. ```python timespan_field = record['Timespan'] assert isinstance(timespan_field, datetime.timedelta) assert isinstance(timespan_field, pendulum.Duration) ``` -------------------------------- ### Bulk Deleting Records by Instance - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Illustrates deleting multiple records by passing record instances to the `app.records.bulk_delete` method. Records must first be retrieved, for example, using `app.records.get` by their tracking ID. ```python # Delete by record record1 = app.records.get(tracking_id='APP-1') record2 = app.records.get(tracking_id='APP-2') record3 = app.records.get(tracking_id='APP-3') app.records.bulk_delete(record1, record2, record3) ``` -------------------------------- ### Retrieving Swimlane Records by ID - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates how to retrieve a specific Swimlane record from an app using either its tracking ID or its unique record ID. It shows how to get the app instance first and then use the `app.records.get` method. Requires an existing app instance and valid record/tracking IDs. ```python app = swimlane.apps.get(name='Target App') # Get by Tracking ID record_from_tracking = app.records.get(tracking_id='APP-1') # Get by Record ID record_from_id = app.records.get(id='58f...387') assert record_from_tracking == record_from_id ``` -------------------------------- ### Using Python Time Field Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Documentation and examples for the Time field type, which returns `pendulum.Time` instances. The code demonstrates accessing the field, asserting its type, and setting the value using both full datetimes and time-only instances, showing that the date portion is dropped. Note that Time instances do not respect timezone information. ```python time_field = record['Time'] assert isinstance(time_field, datetime.time) assert isinstance(time_field, pendulum.Time) # Set to full datetime, date portion is dropped and Time instance is always returned record['Time'] = pendulum.now() assert isinstance(record['Time'], pendulum.Time) # Set to just time record['Time'] = pendulum.now().time() assert isinstance(record['Time'], pendulum.Time) ``` -------------------------------- ### Validating NumericField Input in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Illustrates the validation of a NumericField by attempting to assign a non-numeric string, which raises a ValidationError, and then successfully assigning a valid number. ```python assert isinstance(record['Numeric'], numbers.Number) try: record['Numeric'] = 'Not a Number' except ValidationError: record['Numeric'] = 5 assert record['Numeric'] == 5 ``` -------------------------------- ### Updating TextField with Type Coercion in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how the 'Severity' TextField automatically coerces an integer value back to a string after an arithmetic operation, illustrating the automatic type handling. ```python # Coerce to int, add, and automatically set back to str type in field assert record['Severity'] == '7' # Update value, setting the text field to an int record['Severity'] = int(record['Severity']) + 1 # Value has been coerced to a string assert isinstance(record['Severity'], str) assert record['Severity'] == '8' ``` -------------------------------- ### Overriding Reference Field (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how to completely replace the existing references in a reference field by assigning a list containing the desired target record(s). Asserts the field now contains only the assigned record. ```python # Can be set to a list of records directly # Acts similar to values list, any invalid records cause the entire operation to fail record['Reference'] = [ref_target_record] assert len(record['Reference']) == 1 ``` -------------------------------- ### Managing Comments Field (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates accessing the 'Comments' field, which returns a `CommentCursor`. Shows how to iterate through existing comments, check their types and properties, and add new comments (plain text and rich text) using the cursor's `comment` method. ```python comments = record['Comments'] assert isinstance(comments, CommentCursor) assert len(comments) == 1 for comment in comments: # Yields Comment instances assert isinstance(comment, Comment) assert isinstance(comment.message, str) assert isinstance(comment.user, UserGroup) assert isinstance(comment.created_date, datetime) assert isinstance(comment.is_rich_text, boolean) # Add new comment comments.comment('New comment message') # Add new rich text comment comments.comment('

New Comment

', rich_text=True) # Not persisted until saved, but still listed on local record assert len(comments) == 2 assert comments[1].message == str(comments[1]) == 'New comment message' ``` -------------------------------- ### Comparing DatetimeField with Nanoseconds in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Highlights the potential inconsistency when comparing a DatetimeField value (which has millisecond resolution) with a `pendulum.now()` instance that may have nanosecond resolution, showing they will not be equal. ```python # 2017-09-20 12:34:56.987654 now = pendulum.now() # 2017-09-20 12:34:56.987000 record['Datetime'] = now assert record['Datetime'] != now ``` -------------------------------- ### Iterating Over Reference Field - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Explains how to access the Reference field cursor, assert its type, check the number of references, and iterate through referenced Record instances, asserting their type and confirming they belong to the target app. ```python reference = record['Reference'] assert isinstance(reference, ReferenceCursor) assert len(reference) == 3 for referenced_record in reference: assert isinstance(referenced_record, Record) assert referenced_record._app != app assert referenced_record._app == reference.target_app ``` -------------------------------- ### Comparing DatetimeField by Rounding Microseconds in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Offers another method for comparing DatetimeField values with potentially higher-resolution datetimes by rounding the comparison value to the millisecond level before checking for equality. ```python ## Rounding comparison # 2017-09-20 12:34:56.987654 now = pendulum.now() # 2017-09-20 12:34:56.987000 record['Datetime'] = now # 2017-09-20 12:34:56.987000 rounded_now = now.replace( microsecond=math.floor(now.microsecond / 1000) * 1000 ) assert record['Datetime'] == rounded_now ``` -------------------------------- ### Setting DatetimeField (Date & Time) with Pendulum in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how to access a 'Datetime' field (Date & Time subtype), verify its type as both `datetime.datetime` and `pendulum.Pendulum`, set it using a Pendulum instance, and demonstrates that setting it with a generic string fails validation. ```python datetime_field_value = record['Datetime'] # Drop-in replacement and extension of Python's builtin datetime assert isinstance(datetime_field_value, datetime.datetime) assert isinstance(datetime_field_value, pendulum.Pendulum) assert datetime_field_value.year == 2017 assert datetime_field_value.month == 4 assert datetime_field_value.day == 10 assert datetime_field_value.hour == 16 # Set to a datetime/pendulum instance # See warning below record['Datetime'] = now = pendulum.now().replace(microseconds=0) # Fail on generic timestamp/string (not enough context to guarantee consistent behavior) try: record['Datetime'] = '2017-05-11 11:10:09' except ValidationError: pass assert record['Datetime'] == now ``` -------------------------------- ### Setting UserGroup Field with Validation - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates setting a UserGroup field with a valid User instance and shows that attempting to set it with an ambiguous string value like 'Everyone' will raise a ValidationError, which is caught. ```python record['UserGroup'] = swimlane.user try: record['UserGroup'] = 'Everyone' except ValidationError: # Will not work, string is ambiguous and not a valid value pass assert record['UserGroup'] == swimlane.user ``` -------------------------------- ### Accessing Readonly TrackingIdField in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates accessing the read-only 'Tracking Id' field and shows that attempting to modify it raises a ValidationError, confirming its read-only nature. ```python assert record['Tracking Id'] == 'RA-7' try: record['Tracking Id'] = 'New Tracking ID' except ValidationError: assert record['Tracking Id'] == 'RA-7' ``` -------------------------------- ### Getting Swimlane Groups by ID or Name (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates retrieving a single Swimlane group object using either its unique identifier ('id') or its display name ('name') via the 'swimlane.groups.get()' method. ```python group_by_id = swimlane.groups.get(id='58f...387') group_by_display_name = swimlane.groups.get(name='Everyone') ``` -------------------------------- ### Retrieving and Asserting UserGroup Field - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Illustrates how to access a UserGroup field, assert that the returned value is a UserGroup instance, verify its properties like ID and name, and compare it with another UserGroup instance retrieved via the API. ```python usergroup = record['Group'] assert isinstance(usergroup, UserGroup) assert usergroup.id == '58de1d1c07637a0264c0ca71' assert usergroup.name == 'Everyone' # UserGroup comparisons with specific User/Group instances assert usergroup == swimlane.groups.get(name='Everyone') ``` -------------------------------- ### Clearing All Attachments - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how to remove all attachments from a record by using the `del` keyword on the attachment field. Notes that the change is not persisted on the server until `record.save()` is called. ```python assert len(record['Attachment']) == 1 del record['Attachment'] assert len(record['Attachment']) == 0 # Not cleared on server until saved record.save() ``` -------------------------------- ### Comparing DatetimeField by Removing Microseconds in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Provides a solution for accurate equality comparison by demonstrating how to remove the microsecond component from a `pendulum.now()` instance before setting the field, ensuring the stored value and the comparison value have the same resolution. ```python # 2017-09-20 12:34:56.000000 now = pendulum.now().replace(microsecond=0) # 2017-09-20 12:34:56.000000 record['Datetime'] = now assert record['Datetime'] == now ``` -------------------------------- ### Validating Text List Field Values - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Shows how attempting to set a Text List field with invalid values (e.g., an integer) will raise a ValidationError, and how to catch this exception. ```python try: record['Text List Field'] = ['text', 456] except ValidationError: assert list(record['Text List Field']) == ['new', 'values'] ``` -------------------------------- ### Retrieving Record Revisions in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates how to access and retrieve historical revisions of a Swimlane record. It shows how to get all revisions, retrieve a specific revision by number, and access the historical version of the application associated with that revision. ```python # get all revisions record_revisions = record.revisions.get_all() # get by revision number record_revision = record.revisions.get(2) # get the historical version of the app # automatically retrieves the corresponding app revision to create the Record object historical_record_version = record_revision.version ``` -------------------------------- ### Attempting Invalid Reference Add (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Demonstrates attempting to add a record to a reference field where the record's app does not match the target app of the reference field. This operation is expected to raise a `ValidationError`. ```python try: record['Reference'].add(record) except ValidationError: assert len(record['Reference']) == 3 ``` -------------------------------- ### Serializing Record/Fields to JSON in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates how to convert a Swimlane record or specific fields into a JSON-compatible dictionary using the `for_json()` method. This is useful for pretty printing or serialization, especially for complex field types. It shows examples for the whole record, a subset of fields, a single field, and specific field types like UserGroup or Comments. ```python import json # Quick serialize all fields on record to readable JSON-compatible format dict print(json.dumps( record.for_json(), indent=4 )) # Specify subset of fields to include in output dict print(json.dumps( record.for_json('Target Field 1', 'Target Field 2', ...), indent=4 )) # Get a single field's JSON-compatible value print(json.dumps( record.get_field('Target Field').for_json() )) # Attachments, Comments, UserGroups, and any Cursors can all be converted to JSON-compatible values directly print(json.dumps( record['User Group Field'].for_json() )) print(json.dumps( record['Comments Field'][2].for_json() )) ``` -------------------------------- ### Checking Swimlane Bulk Job Status (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates how to initiate a bulk record modification job using 'app.records.bulk_modify()' and then check the status of the asynchronous job using 'swimlane.helpers.check_bulk_job_status()'. The example output shows the possible status transitions. ```python # Get target app app = swimlane.apps.get(name='App') # Bulk modify records matching filters job_id = app.records.bulk_modify( ('Numeric', 'equals', 1), values={'Numeric': 2} ) # Check bulk job status status = swimlane.helpers.check_bulk_job_status(job_id) print(status) ``` -------------------------------- ### Setting Multi Select ValuesListField Directly in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst This snippet demonstrates setting the Multi Select ValuesListField directly to an iterable, overwriting the current selection. It shows setting it to an empty list and attempting to set it with a list containing an invalid option, illustrating that the entire operation fails if any element is invalid. ```python vl_original_values = list(record['Values List']) record['Values List'] = [] assert len(record['Values List']) == 0 # All elements must pass validation, or entire set operation fails try: record['Values List'] = ['Option 1', 'Not a valid option'] except ValidationError: assert len(record['Values List']) == 0 record['Values List'] = vl_original_values assert len(record['Values List']) == 2 ``` -------------------------------- ### Listing All Apps (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to retrieve a list of all available application resources using the `swimlane.apps.list()` method. ```python apps = swimlane.apps.list() ``` -------------------------------- ### Asserting Datetime Difference in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst This snippet asserts that the time difference between a 'Datetime' field in a record and the current time ('now') is within a small tolerance (less than 0.001 seconds). This is likely used for testing the precision of datetime handling. ```python assert abs((record['Datetime'] - now).total_seconds()) < 0.001 ``` -------------------------------- ### Creating Single Record - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates creating a single new record using the `app.records.create` adapter. It shows how to provide initial field values as keyword arguments and notes that default selection field values are included unless overridden. The newly created record object is returned after being persisted on the server. ```python new_record = app.records.create(**{ 'Text Field': 'Field Value', 'Numeric Field': 50, ... }) ``` -------------------------------- ### Attempting Invalid Reference Override (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/fields.rst Illustrates attempting to override a reference field with a list containing an invalid item (like an ID instead of a record object). This operation is expected to raise a `ValidationError`, leaving the field unchanged. ```python try: record['Reference'] = [ref_id, ref_target_record] except ValidationError: assert len(record['Reference']) == 1 ``` -------------------------------- ### Listing All Users (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to retrieve a list of all available user resources using the `swimlane.users.list()` method. ```python users = swimlane.users.list() ``` -------------------------------- ### Connect Swimlane Client and Create Record Source: https://github.com/swimlane/swimlane-python/blob/master/docs/index.rst Shows how to initialize the Swimlane client both outside and inside a Swimlane Python task, retrieve an application by name, and create a new record with various field types. ```Python from swimlane import Swimlane # Connect Swimlane client outside of Swimlane swimlane = Swimlane('https://192.168.1.1', 'username', 'password') # Connect Swimlane client from Python task in Swimlane swimlane = Swimlane(sw_context.config['InternalSwimlaneUrl'],'username','password') # Retrieve App by name app = swimlane.apps.get(name='Target App') # Create new Record new_record = app.records.create(**{ 'Text Field': 'String', 'Numeric Field': 100, 'UserGroup Field': swimlane.user, 'ValuesList Field': ['Option 1', 'Option 2'] }) # Work with field values assert new_record['Text Field'] == 'String' ``` -------------------------------- ### Initializing Swimlane Client with Access Token (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to initialize the Swimlane client using a personal access token instead of a username and password for authentication. ```python from swimlane import Swimlane swimlane = Swimlane('192.168.1.1', access_token='abcdefg') ``` -------------------------------- ### Initializing Client with Write to Read-Only (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to initialize the Swimlane client with the `write_to_read_only` parameter set to `True` to enable modifying fields marked as read-only in the application builder. It then demonstrates retrieving an app and record and setting a value for a read-only field before saving. ```python from swimlane import Swimlane swimlane = Swimlane( '192.168.1.1', 'username', 'password', write_to_read_only=True) app = swimlane.apps.get(id='abc...123') record = app.records.get(id='def...456') record['Read-Only Field'] = "New Value" record.save() ``` -------------------------------- ### Accessing App and Record Data (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates how to retrieve an application resource by ID, then retrieve a record resource within that app by ID, and finally iterate through items in a reference field within the record. ```python app = swimlane.apps.get(id='abc...123') print(app) record = app.records.get(id='def...456') print(record) for reference_record in record['Reference Field']: print(reference_record) ``` -------------------------------- ### Listing All Swimlane Groups (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to fetch a list of all available Swimlane groups using the 'swimlane.groups.list()' method. This returns a collection of group objects. ```python groups = swimlane.groups.list() ``` -------------------------------- ### Building and Iterating Swimlane Reports - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates using the `app.reports.build` method to create a Report object for handling large search results. Filters are applied individually using `report.filter`. Records are retrieved on-demand during iteration, which is more memory-efficient than `app.records.search` for large results. Shows how to iterate and process records. ```python # Create initial report, with optional limit and keywords filter report = app.reports.build('report-name', limit=0, keywords=['target', 'keywords']) # Apply report filters # These work like search filters, but must be applied one-by-one and are NOT tuples like in app.records.search() report.filter('Text Field', 'equals', 'value') report.filter('Numeric Field', 'equals', 0) # Each record is retrieved from the API on-demand before each iteration for record in report: # Do something with each retrieved record record['Test Field'] = 'modified' if some_condition: # No additional records will be retrieved from report after breaking out of loop break # Report results are cached after first iteration, will not make additional requests or retrieve any skipped results ``` -------------------------------- ### Searching Swimlane Records with Keywords - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Illustrates how to perform a keyword search across all fields of records within a Swimlane app. The `keywords` parameter accepts a list of strings. Records matching any of the keywords in any field will be returned. Requires an app instance and a list of keywords. ```python records = app.records.search( keywords=[ 'target', 'keywords' ] ) ``` -------------------------------- ### Searching Swimlane Records with Pagination - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to use pagination parameters (`page_size`, `page_start`, `page_end`) in conjunction with `limit=0` to retrieve specific ranges of pages from a large search result. This helps manage memory and avoid timeouts by processing results in chunks. Requires an app instance, search criteria, and `limit=0`. ```python # retrieve all results records = app.records.search( ('Text Field', 'equals', 'value'), ... limit=0, page_size=100 page_start=5, page_end=8 ) ``` -------------------------------- ### Connecting via HTTP with Swimlane Client (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Illustrates how to connect to a Swimlane server using plain HTTP by explicitly including the 'http://' scheme in the host URL. Note that this method is not recommended for production environments. ```python from swimlane import Swimlane swimlane = Swimlane('http://192.168.1.1', 'username', 'password') ``` -------------------------------- ### Bulk Creating Records - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to create multiple records efficiently in a single request using `app.records.bulk_create`. It takes multiple dictionaries as arguments, where each dictionary represents a record's initial field values. The entire operation fails if any record does not pass validation. ```python records = app.records.bulk_create( {'Text Field': 'Value 1', 'Numeric Field': 10, ...}, {'Text Field': 'Value 2', 'Numeric Field': 20, ...}, ... ) ``` -------------------------------- ### Searching Swimlane Records with No Limit - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Explains how to override the default search limit (50 records) to retrieve all matching records by setting the `limit` parameter to `0`. Warns that this can be an expensive operation and potentially cause timeouts for large result sets. Requires an app instance and search criteria. ```python # retrieve all results records = app.records.search( ('Text Field', 'equals', 'value'), ... limit=0 ) ``` -------------------------------- ### Adding Record References using Helpers (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Illustrates the use of the 'swimlane.helpers.add_record_references()' method to link multiple target records to a specific field on a source record within a Swimlane application. Requires application, source record, field, and target record IDs. ```python swimlane.helpers.add_record_references( app_id='123...456', record_id='789...0ab', field_id='abc...def', target_record_ids=[ '123...456', '789...0ab', 'cde...f12', ... ] ) ``` -------------------------------- ### Searching Swimlane Records with Filters - Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to search for records within a Swimlane app using multiple filter conditions. Filters are provided as tuples `(field_name, filter_operator, field_value)` and are combined with an AND logic. Requires an app instance and valid field names, operators, and values. ```python records = app.records.search( ('Text Field', 'equals', 'value'), ('Date Field', 'lessThan', pendulum.now()), ('Values List (Multi-Select)', 'equals', ['Option 1', 'Option 2']) ('Reference (Single-Select)', 'equals', target_record) ) ``` -------------------------------- ### Handling Unknown Field Errors in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to handle `UnknownField` exceptions that occur when attempting to access or set a field that does not exist on the record's parent application. The exception includes the invalid field name and potentially similar names. ```python try: record['Rext'] = 'New Text' except UnknownField as error: print(error) ``` -------------------------------- ### Bulk Modifying Records by Instance - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates modifying multiple records by providing a list of record instances and a dictionary of field values to update. Invalid field values for any record will cause the entire operation to fail. ```python # Bulk modify multiple record instances record1 = app.records.get(tracking_id='APP-1') record2 = app.records.get(tracking_id='APP-2') record3 = app.records.get(tracking_id='APP-3') ... app.records.bulk_modify( record1, record2, record3, ... values={ 'Field Name': 'New Value', ... } ) ``` -------------------------------- ### Comparing UserGroup, User, and Group Objects in Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates that UserGroup instances can be directly compared for equality with User or Group instances if they represent the same underlying entity in Swimlane. ```python assert record['Created By'] == swimlane.user assert record['Group'] == swimlane.groups.get(name='Everyone') ``` -------------------------------- ### Setting Record Field Values - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Illustrates how to set or update the value of a field on a record instance by assigning a new value using the field name as a dictionary key. This works the same way as accessing values. ```python record['Text'] = 'New Text' ``` -------------------------------- ### Setting Global Request Timeout (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates how to configure a global default timeout for all requests made by the Swimlane client by providing the `default_timeout` parameter in seconds during client instantiation. ```python from swimlane import Swimlane swimlane = Swimlane( '192.168.1.1', 'username', 'password', default_timeout=300 ) ``` -------------------------------- ### Accessing and Setting User/Group Fields in Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates that fields representing users or groups initially return UserGroup instances when accessed, but can be directly assigned instances of the more specific User or Group types. ```python # User / Group fields return UserGroup instances when accessed assert type(record['Created By']) is UserGroup # But can be set to the more specific User / Group types directly record['User'] = swimlane.user record['Group'] = swimlane.groups.get(name='Everyone') ``` -------------------------------- ### Project Dependencies - Python Source: https://github.com/swimlane/swimlane-python/blob/master/requirements.txt This list specifies the external Python libraries and their required versions or version ranges that the project depends on. It ensures a consistent environment for development and deployment. ```Python cachetools>=4.2.4 certifi==2024.7.4 pendulum==2.1.2; python_version<='3.7' pendulum==3.0.0; python_version>='3.8' pyjwt>=2.4.0 pyuri>=0.3,<0.4 requests[security]>=2,<3 six>=1.12.0 sortedcontainers==2.4.0 shortid==0.1.2 ``` -------------------------------- ### Saving Record Changes in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Illustrates how to persist local changes made to a Swimlane record object to the server. Changes are only applied locally until the `save()` method is explicitly called. ```python record['Text'] = 'Some New Text' record.save() ``` -------------------------------- ### Setting Per-Request Timeout (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Shows how to override the global default timeout for a specific request by passing the optional `timeout` parameter to the `swimlane.Swimlane.request` method. ```python from swimlane import Swimlane swimlane = Swimlane('192.168.1.1', 'username', 'password') # Potentially long delay before starting response with 10 minute timeout response = swimlane.request( 'post', 'some/endpoint', ..., timeout=600 ) ``` -------------------------------- ### Accessing Record Fields by Key - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows that record fields can also be accessed using their optional field keys, which point to the same field as the readable name. ```python # The field key points to the same field as the field name assert record['Field'] == record['field-key'] ``` -------------------------------- ### Disabling Server Version Verification (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Explains how to disable the default check that verifies if the major versions of the client and server match during client initialization by setting the `verify_server_version` parameter to `False`. ```python from swimlane import Swimlane swimlane = Swimlane( '192.168.1.1', 'username', 'password', verify_server_version=False ) ``` -------------------------------- ### Bulk Modifying Records by Filter - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to modify multiple records based on query filters without needing to retrieve record instances first. Filters are provided as tuples, followed by a `values` dictionary specifying the fields and their new values. ```python # Modify by filter(s) app.records.bulk_modify( # Query filters ("Text Field", "equals", "Value"), ("Number Field", "equals", 2), # New values for records values={ "Field Name": "New Value", "Numeric Field": 10, ... } ) ``` -------------------------------- ### Accessing Record Fields by Name - Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Demonstrates accessing individual field values on a record instance using the field's readable name as a dictionary key. Field names are case and whitespace sensitive. Fields without a value default to `None`. ```python # The "Text" field has a value of 'Some Example Text' assert record['Text'] == 'Some Example Text' # Any fields without a value default to `None`. assert record['Empty Field'] == None ``` -------------------------------- ### Specify Sphinx Dependency Version (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/requirements.txt This line specifies a dependency on the 'sphinx' package, requiring a version that is greater than or equal to 6 and strictly less than 7. This ensures compatibility with a specific range of the library. ```Python sphinx>=6,<7 ``` -------------------------------- ### Configuring Retry Options for Swimlane Client (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Demonstrates how to override the default retry options for server errors (HTTP 5XX) by providing `retry`, `max_retries`, and `retry_interval` parameters during client initialization. These settings apply globally to all requests. ```python from swimlane import Swimlane swimlane = Swimlane( '192.168.1.1', 'username', 'password', retry=True, max_retries=3, retry_interval=10 # in seconds ) ``` -------------------------------- ### Run Pytest with Custom Parameters Source: https://github.com/swimlane/swimlane-python/blob/master/README.rst Executes the pytest test suite, allowing override of the target Swimlane server URL, user, password, and enabling version verification skip. ```Shell pytest --url default="https://localhost" --user default="admin" --pass This is the password for the user defined above. --skipverify This is for allowing the version of PyDriver to not match the version of Swimlane. ``` -------------------------------- ### Managing Record Restrictions in Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Explains how to modify the set of users allowed to modify a Swimlane record using the `add_restriction()` and `remove_restriction()` methods. It shows how to add users, remove specific users, or clear all restrictions. ```python # Add user(s) to set of users allowed to modify record record.add_restriction(swimlane.user, other_user) # Remove one or more users from restriction set record.remove_restriction(swimlane.user) # Clear the entire restricted user set record.remove_restriction() ``` -------------------------------- ### Iterating Through Users in a Group in Swimlane Python Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/resources.rst Shows how to access the users property of a Group object to iterate over the individual User instances belonging to that group. ```python group = swimlane.groups.get(name='Everyone') for user in group.users: assert isinstance(user, User) ``` -------------------------------- ### Performing Custom Direct API Requests (Python) Source: https://github.com/swimlane/swimlane-python/blob/master/docs/examples/client.rst Illustrates how to use the `swimlane.Swimlane.request` method to perform custom HTTP requests to API endpoints that may not be fully supported by internal adapters or require special arguments. This method reuses the underlying connection session and handles authentication automatically. ```python from swimlane import Swimlane swimlane = Swimlane('192.168.1.1', 'username', 'password') response = swimlane.request( 'post', 'some/endpoint', json={...}, params={...}, ... ) ```