### Install pykechain from source Source: https://pykechain.readthedocs.io/en/stable?badge=stable Install the latest development version directly from the GitHub repository. ```bash pip install https://github.com/KE-works/pykechain/archive/main.zip ``` -------------------------------- ### Install pykechain via pip Source: https://pykechain.readthedocs.io/en/stable/index.html Standard installation command for the pykechain library. ```bash pip install pykechain ``` ```bash pip install https://github.com/KE-works/pykechain/archive/main.zip ``` -------------------------------- ### Apply Form Transition Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/form.html Example of applying a specific transition to a form using a known workflow. ```python >>> transition = workflow.transition("In progress") >>> form.apply_transition(transition=transition) ``` -------------------------------- ### Clone a Part Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/part.html Demonstrates cloning a part, with an optional example for KE-chain 3 backends specifying name and multiplicity. ```python >>> bike = project.model('Bike') >>> bike2 = bike.clone() ``` ```python >>> bike = project.model('Bike') >>> bike2 = bike.clone(name='Trike', multiplicity=Multiplicity.ZERO_MANY) ``` -------------------------------- ### Retrieve Parts with Filters Source: https://pykechain.readthedocs.io/en/stable/api/client.html Examples demonstrating how to filter parts by name, category, or limit the number of results returned. ```python >>> client = Client(url='https://default.localhost:9443', verify=False) >>> client.login('admin','pass') >>> client.parts(name='Gears') ``` ```python >>> client.parts(name='Gears', category=None) ``` ```python >>> client.parts(limit=5) ``` -------------------------------- ### Retrieve Team Members Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/team.html Example showing how to fetch members of a specific team using the client. ```python >>> my_team = client.team(name='My own team') >>> my_team.members() [{"pk":1, "username"="first user", "role"="OWNER", "email":"email@address.com"}, ...] ``` -------------------------------- ### Retrieve Part Instances Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/part.html Use these examples to fetch instances associated with a model part, optionally filtering by name. ```python >>> wheel_model = project.model('Wheel') >>> wheel_instance_set = wheel_model.instances() ``` ```python >>> wheel_model = project.model('Wheel') >>> front_wheel_instances = wheel_model.instances(name__contains='Front') ``` -------------------------------- ### Create Weather Widget Implementation Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widgets_manager.html Internal logic for initializing and creating a weather widget, including metadata setup and property association. ```python weather_property: "Property" = _retrieve_object( weather_property, method=self._client.property ) meta = _initiate_meta(kwargs, activity=self.activity) if weather_property.category == Category.MODEL: weather_model_id = weather_property.id weather_instance_id = None else: weather_model_id = weather_property.model_id weather_instance_id = weather_property.id meta = _initiate_meta(kwargs, activity=self.activity) meta, title = _set_title(meta, title=title, **kwargs) meta.update( { AssociatedObjectId.PROPERTY_INSTANCE_ID: weather_instance_id, AssociatedObjectId.PROPERTY_MODEL_ID: weather_model_id, } ) widget = self.create_widget( widget_type=WidgetTypes.WEATHER, meta=meta, title=title, parent=parent_widget, writable_models=[weather_model_id], **kwargs, ) return widget ``` -------------------------------- ### Define Widget Classes Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widget_models.html Examples of widget class definitions inheriting from the base Widget class. ```python from pykechain.models.widgets.widget import Widget from pykechain.models.widgets.widget_schemas import undefined_meta_schema class MetapanelWidget(Widget): """Metapanel Widget.""" class FormmetapanelWidget(Widget): """FormMetapanel Widget.""" class PropertygridWidget(Widget): """Propertygrid Widget.""" class UndefinedWidget(Widget): """Undefined Widget.""" schema = undefined_meta_schema class FilteredgridWidget(Widget): """Filteredgrid Widget.""" class SupergridWidget(Widget): """Supergrid Widget.""" class AttachmentviewerWidget(Widget): """Attachmentviewer Widget.""" class MultiAttachmentviewerWidget(Widget): """Multi Attachmentviewer Widget.""" class TasknavigationbarWidget(Widget): """Tasknavigationbar Widget.""" class HtmlWidget(Widget): """HTML Widget.""" class MarkdownWidget(Widget): """HTML Widget.""" class ServiceWidget(Widget): """Service Widget.""" class NotebookWidget(Widget): """Notebook Widget.""" class JsonWidget(Widget): """JSON Widget.""" class MulticolumnWidget(Widget): """Multicolumn Widget.""" class ProgressWidget(Widget): """ Progress bar Widget. This widget is deprecated as of June 2024. """ class ScopeWidget(Widget): """Scope grid Widget.""" class SignatureWidget(Widget): """Signature Widget.""" class CardWidget(Widget): """Card Widget.""" class ThirdpartyWidget(Widget): """Thirdparty Widget.""" class TasksWidget(Widget): """Tasks Widget.""" class WeatherWidget(Widget): """Weather Widget.""" class ServicecardWidget(Widget): """ServiceCard Widget.""" class DashboardWidget(Widget): """Dashboard Widget.""" class ScopemembersWidget(Widget): """ScopeMembers Widget.""" class ProjectinfoWidget(Widget): """Project Info Widget.""" ``` -------------------------------- ### GeoCoordinateRepresentation Configuration Example Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/representations/representations.html Example structure for GeoCoordinateRepresentation in value_options. ```json # "representations": [ # { # "rtype": "geoCoordinate", # "config": { # "geoCoordinate": "rd_amersfoort" # can be any of GeoCoordinateConfig # } # } # ] # }, ``` -------------------------------- ### Initialize Client from Environment Variables Source: https://pykechain.readthedocs.io/en/stable/api/client.html Configure the client using settings defined in an environment file. Ensure authentication details are provided in the file or set later. ```text # User token here (required) KECHAIN_TOKEN=...... KECHAIN_URL=https://an_url.ke-chain.com # or use Basic Auth with username/password KECHAIN_USERNAME=... KECHAIN_PASSWORD=... # optional add a scope name or scope id KECHAIN_SCOPE=... KECHAIN_SCOPE_ID=... ``` ```python >>> client = Client().from_env() ``` -------------------------------- ### Retrieve project using a .env file Source: https://pykechain.readthedocs.io/en/stable/api/helpers.html Load configuration from a local .env file to initialize the project. ```text # This is an .env file on disk. KECHAIN_TOKEN=bd9377793f7e74a29dbb11fce969 KECHAIN_URL=http://localhost:8080 KECHAIN_CHECK_CERTIFICATES=False KECHAIN_SCOPE_ID=c9f0-228e-4d3a-9dc0-ec5a75d7 ``` ```python >>> project = get_project(env_filename='/path/to/.env') >>> project.id c9f0-228e-4d3a-9dc0-ec5a75d7 ``` -------------------------------- ### Create a model with properties using Python Source: https://pykechain.readthedocs.io/en/stable/api/client.html Demonstrates initializing a client and creating a new model with a list of property definitions, including a required field validator. ```python >>> from pykechain.models.validators import RequiredFieldValidator >>> properties_fvalues = [ ... {"name": "char prop", "property_type": PropertyType.CHAR_VALUE, "order": 1}, ... {"name": "number prop", "property_type": PropertyType.FLOAT_VALUE, "value": 3.14, "order": 2}, ... {"name": "boolean_prop", "property_type": PropertyType.BOOLEAN_VALUE, "value": False, ... "value_options": {"validators": [RequiredFieldValidator().as_json()]}, "order":3} ... ] >>> client = Client() >>> new_model = client.create_model_with_properties(name='A new model', parent='', ... multiplicity=Multiplicity.ONE, ... properties_fvalues=properties_fvalues) ``` -------------------------------- ### Get signature filename Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/property_reference.html Returns the filename of the file stored in the signature property. ```python @property def filename(self) -> Optional[Union[str, list]]: """Filename of the file stored in the signature property.""" if self.value: return self.value.filename else: return None ``` -------------------------------- ### Get filename(s) Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/property_reference.html Returns the filename or a list of filenames for the files stored in the property. ```python @property def filename(self) -> Optional[Union[str, list]]: """Filename or list of filenames of the file(s) stored in the property.""" if self.value: if len(self.value) == 1: return self.value[0].filename else: return [stored_file.filename for stored_file in self.value] else: return None ``` -------------------------------- ### Retrieve a project using a .env file Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/helpers.html This approach loads configuration from a specified environment file on disk. ```python >>> project = get_project(env_filename='/path/to/.env') >>> project.id c9f0-228e-4d3a-9dc0-ec5a75d7 ``` -------------------------------- ### Manage Workflow Status Order Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/workflow.html Get or set the order of statuses within a workflow. ```python @property def status_order(self) -> List[Status]: """Statuses in the right order.""" return self.statuses @status_order.setter def status_order(self, value: List[Union[ObjectID, Status]]): """ Set the order of the statuses specifically in a certain order. :param value: a determined ordered list of Status or status UUID's """ if not value: raise IllegalArgumentError( f"To set the order of statises, provide a list of status objects, got: '{value}'" ) data = {"status_order": check_list_of_base(value, Status, "statuses")} url = self._client._build_url("workflow_set_status_order", workflow_id=self.id) response = self._client._request("PUT", url=url, json=data) if response.status_code != requests.codes.ok: # pragma: no cover raise APIError( "Could not alter the order of the statuses", response=response ) self.refresh(json=response.json()["results"][0]) ``` -------------------------------- ### from_env(env_filename, check_certificates) Source: https://pykechain.readthedocs.io/en/stable/api/client.html Creates a client instance using settings defined in an environment file. ```APIDOC ## from_env(env_filename, check_certificates) ### Description Initiates the pykechain client from the contents of an environment file. ### Parameters - **env_filename** (str) - Optional - Filename of the environment file (defaults to '.env'). - **check_certificates** (bool) - Optional - Whether to check TLS/SSL certificates (defaults to True). ``` -------------------------------- ### Initialize the KE-chain Client Source: https://pykechain.readthedocs.io/en/stable/api/client.html Create a new client instance by specifying the URL and TLS certificate verification settings. ```python >>> from pykechain import Client >>> client = Client() ``` ```python >>> from pykechain import Client >>> client = Client(url='https://default-tst.localhost:9443', check_certificates=False) ``` -------------------------------- ### Retrieve Scopes Source: https://pykechain.readthedocs.io/en/stable/api/client.html Demonstrates initializing the client, logging in, and listing available scopes. ```python >>> client = Client(url='https://default.localhost:9443', verify=False) >>> client.login('admin','pass') >>> client.scopes() ... ``` ```python >>> client.scopes(name="Bike Project") ... ``` -------------------------------- ### Sidebar Card JSON Configuration Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/sidebar/sidebar_card.html Example of the JSON structure used to define a sidebar card. ```json { "itemType": "CARD", "order": 5, "align": "top", "showCloseAction": true, "showActionButton": true, "actionButtonUri": "https://asdasdas", "actionButtonUriTarget": "_new", "actionButtonName": "Discover more", "displayText": "This project ...", "displayText_nl": "Dit project ...", "displayTextAlign": "left", "showBackground": true, "minimumAccessLevel": "is_member", "maximumAccessLevel": "is_supervisor", } ``` -------------------------------- ### Initialize KE-chain Client from Environment or Arguments Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/helpers.html Handles client connection logic by checking environment variables or provided arguments, enforcing credential requirements, and returning a scope object. ```python if env.bool(kecenv.KECHAIN_FORCE_ENV_USE, default=False): if not os.getenv(kecenv.KECHAIN_URL): raise ClientError( "Error: KECHAIN_URL should be provided as environment variable (use of env vars is" " enforced)" ) if not ( os.getenv(kecenv.KECHAIN_TOKEN) or ( # noqa: W504 os.getenv(kecenv.KECHAIN_PASSWORD) and os.getenv(kecenv.KECHAIN_PASSWORD) ) ): raise ClientError( "Error: KECHAIN_TOKEN or KECHAIN_USERNAME and KECHAIN_PASSWORD should be provided" " as environment variable(s) (use of env vars is enforced)" ) if not (os.getenv(kecenv.KECHAIN_SCOPE) or os.getenv(kecenv.KECHAIN_SCOPE_ID)): raise ClientError( "Error: KECHAIN_SCOPE or KECHAIN_SCOPE_ID should be provided as environment" " variable (use of env vars is enforced)" ) if env.bool(kecenv.KECHAIN_FORCE_ENV_USE, default=False) or not any( (url, username, password, token, scope, scope_id) ): check_certificates = env.bool(kecenv.KECHAIN_CHECK_CERTIFICATES, default=True) client = Client.from_env( env_filename=env_filename, check_certificates=check_certificates ) scope_id = env(kecenv.KECHAIN_SCOPE_ID, default=None) scope = env(kecenv.KECHAIN_SCOPE, default=None) status = env(kecenv.KECHAIN_SCOPE_STATUS, default=None) elif ( url and ((username and password) or (token)) and (scope or scope_id) ) and not env.bool(kecenv.KECHAIN_FORCE_ENV_USE, default=False): if check_certificates is None: check_certificates = env.bool( kecenv.KECHAIN_CHECK_CERTIFICATES, default=True ) client = Client(url=url, check_certificates=check_certificates) client.login(username=username, password=password, token=token) else: raise ClientError( "Error: insufficient arguments to connect to KE-chain. " "See documentation of `pykechain.get_project()`" ) if scope_id: return client.scope(pk=scope_id, status=status) else: return client.scope(name=scope, status=status) ``` -------------------------------- ### Authenticate with KE-chain Client Source: https://pykechain.readthedocs.io/en/stable/index.html Initialize the client and authenticate using a URL, username, and password. ```python from pykechain import Client kec = Client(url='https://.ke-chain.com') kec.login(username='demo_user', password='pastaplease') ``` -------------------------------- ### Retrieve Workflow Objects Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/workflow.html Methods to list or get a single workflow instance using the client. ```python @classmethod def list(cls, client: "Client", **kwargs) -> List["Workflow"]: """Retrieve a list of Workflow objects through the client.""" return super().list(client=client, **kwargs) ``` ```python @classmethod def get(cls, client: "Client", **kwargs) -> "Workflow": """Retrieve a single Workflow object using the client.""" return super().get(client=client, **kwargs) ``` -------------------------------- ### Client(url, check_certificates) Source: https://pykechain.readthedocs.io/en/stable/api/client.html Initializes a new KE-chain client instance. ```APIDOC ## Client(url, check_certificates) ### Description Creates a KE-chain client with given settings to connect to a KE-chain instance. ### Parameters - **url** (str) - Optional - The URL of the KE-chain instance (defaults to http://localhost:8000). - **check_certificates** (bool) - Optional - Whether to check TLS/SSL certificates (defaults to True). ``` -------------------------------- ### Add a new part instance with properties Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/part.html Demonstrates creating a new part instance from a model and setting its initial property values. ```python >>> bike = project.part('Bike') >>> wheel_model = project.model('Wheel') >>> bike.add_with_properties(wheel_model, 'Wooden Wheel', {'Spokes': 11, 'Material': 'Wood'}) ``` -------------------------------- ### NumericRangeValidator Usage Examples Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/validators/validators.html Demonstrates basic range validation and step size enforcement using the NumericRangeValidator class. ```python >>> validator = NumericRangeValidator(minvalue=0, maxvalue=50) >>> validator.is_valid(42) True >>> validator.is_valid(50) True >>> validator.is_valid(50.0001) False >>> validator.is_valid(-1) False >>> validator.get_reason() Value '-1' should be between 0 and 50 >>> stepper = NumericRangeValidator(stepsize=1000, enforce_stepsize=True) >>> stepper.is_valid(2000) True ``` -------------------------------- ### Set Form Status Assignees Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/form.html Example of iterating through status forms to build a list of status dictionaries for assignment. ```python >>> for status_form in form.status_forms: >>> status_dict = { >>> "status": status_form.status, >>> "assignees": [user_1, user_2] >>> } >>> status_assignees_list.append(status_dict) >>> self.form.set_status_assignees(statuses=status_assignees_list) ``` -------------------------------- ### Get Current Time in User Timezone Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/user.html Calculates the current time adjusted to the user's configured timezone. ```python [docs] def now_in_my_timezone(self) -> datetime.datetime: """ Get current time in the timezone of the User. Defaults to timezone GMT+1 (Europe/Amsterdam). :return: Current datetime :rtype datetime.datetime """ timezone_definition = self._json_data["timezone"] if timezone_definition: timezone = pytz.timezone(timezone_definition) else: # if there is no timezone set then the Europe/Amsterdam timezone timezone = pytz.timezone("Europe/Amsterdam") # Default is utc timezone utc_time = datetime.datetime.now(tz=pytz.utc) # Convert to local timezone local_time = utc_time.astimezone(timezone) return local_time ``` -------------------------------- ### Connect to KE-chain Source: https://pykechain.readthedocs.io/en/stable/_sources/example_bike.rst.txt Initialize the pykechain client and authenticate with credentials. ```python import pykechain kec = pykechain.Client(url='') kec.login('', '') ``` -------------------------------- ### get_project(url=None, username=None, password=None, token=None, scope=None, scope_id=None, env_filename=None, status=ScopeStatus.ACTIVE, check_certificates=None) Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/helpers.html Retrieves and returns a KE-chain project (Scope) to be used throughout an application. This function bootstraps the connection using provided parameters, environment variables, or a specified .env file. ```APIDOC ## get_project ### Description Retrieves a `pykechain.models.Scope` object. It can be configured via direct arguments, environment variables, or an environment file. ### Parameters - **url** (str, optional) - URL of the KE-chain instance. - **username** (str, optional) - Username for authentication. - **password** (str, optional) - Password for authentication. - **token** (str, optional) - Authentication token. - **scope** (str, optional) - Name of the project/scope to retrieve. - **scope_id** (str, optional) - UUID of the project/scope to retrieve. - **env_filename** (str, optional) - Path to an environment file to bootstrap the client. - **status** (ScopeStatus, optional) - Status of the scope to retrieve (defaults to ScopeStatus.ACTIVE). - **check_certificates** (bool, optional) - Whether to verify TLS/SSL certificates. ### Returns - **pykechain.models.Scope** - The retrieved project scope. ### Raises - **NotFoundError** - If the scope could not be found. - **ClientError** - If the client connection is unsuccessful. - **APIError** - If other errors occur during retrieval. ``` -------------------------------- ### Edit Activity Properties Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/activity.html Update basic activity attributes like name, description, start date, and assignee. ```python >>> from datetime import datetime >>> my_task = project.activity('Specify the wheel diameter') >>> my_task.edit(name='Specify wheel diameter and circumference', ... description='The diameter and circumference are specified in inches', ... start_date=datetime.utcnow(), ... assignee='testuser') ``` -------------------------------- ### Bulk Create Widgets Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widgets_manager.html Creates multiple widgets at once by providing a list of configuration dictionaries. ```python def create_widgets(self, widgets: List[Dict]) -> List[Widget]: """ Create widgets in bulk. :param widgets: list of dicts defining the configuration per widget. :type widgets: List[Dict] :returns list of widgets :rtype: List[Widget] """ # Insert the current widget for widget in widgets: widget["activity"] = self.activity new_widgets = self._client.create_widgets(widgets=widgets) self._widgets.extend(new_widgets) self._widgets.sort(key=lambda w: w.order) return new_widgets ``` -------------------------------- ### Edit scope details Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/scope.html Update basic scope attributes like name, description, start date, and status. ```python >>> from datetime import datetime >>> project.edit(name='New project name',description='Changing the description just because I can', ... start_date=datetime.now(),status=ScopeStatus.CLOSED) ``` -------------------------------- ### Add Parts to Product Source: https://pykechain.readthedocs.io/en/stable/_sources/example_bike.rst.txt Add new wheel parts to the bike instance. ```python front_wheel = bike.add(wheel_model, name='Front Wheel') rear_wheel = bike.add(wheel_model, name='Rear Wheel') ``` -------------------------------- ### Initialize Dashboard Widget Settings Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widgets_manager.html Logic for populating form status and task list configurations based on provided input lists or default values. ```python show_form_status_list = list() if show_form_status is None: for value in DashboardWidgetShowForms.values(): show_form_status_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowForms.values().index( value ), MetaWidget.SELECTED: True, } ) else: check_type(show_form_status, list, "show_form_status") for value in DashboardWidgetShowForms.values(): if value in show_form_status: show_form_status_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowForms.values().index( value ), MetaWidget.SELECTED: True, } ) else: show_form_status_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowForms.values().index( value ), MetaWidget.SELECTED: False, } ) show_tasks_list = list() if show_tasks is None: for value in DashboardWidgetShowTasks.values(): show_tasks_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowTasks.values().index( value ), MetaWidget.SELECTED: True, } ) else: check_type(show_tasks, list, "show_tasks") for value in DashboardWidgetShowTasks.values(): if value in show_tasks: show_tasks_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowTasks.values().index( value ), MetaWidget.SELECTED: True, } ) else: show_tasks_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowTasks.values().index( value ), MetaWidget.SELECTED: False, } ) ``` -------------------------------- ### Update multiple properties with the client Source: https://pykechain.readthedocs.io/en/stable/api/client.html Demonstrates how to retrieve properties and update them in bulk using a list of dictionaries. ```python >>> properties = client.properties(limit=3) >>> update_dicts = [dict(id=p.id, value=p.value) for p in properties] >>> client.update_properties(properties=update_dicts) ``` -------------------------------- ### create_user(username, email, name=None, team_ids=None, timezone=None, language_code=None, send_passwd_link=False, **kwargs) Source: https://pykechain.readthedocs.io/en/stable/api/client.html Create a new user in KE-chain. ```APIDOC ## create_user(username, email, name=None, team_ids=None, timezone=None, language_code=None, send_passwd_link=False, **kwargs) ### Description Create a new User in KE-chain. ### Parameters - **username** (str) - Required - Username for the new user. - **email** (str) - Required - Email address for the new user. - **name** (str | None) - Optional - Name of the user. - **team_ids** (Team | str | UUID | None) - Optional - Team IDs associated with the user. - **timezone** (str | None) - Optional - Timezone for the user. - **language_code** (LanguageCodes | None) - Optional - Language code for the user. - **send_passwd_link** (bool) - Optional - Whether to send a password reset link. - **kwargs** - Optional - Additional keyword arguments. ### Returns - User - The created User object. ``` -------------------------------- ### download_as_excel Source: https://pykechain.readthedocs.io/en/stable/api/models_widgets_widgets.html Exports a grid widget as an Excel file. ```APIDOC ## download_as_excel(target_dir=None, file_name=None, user=None) ### Description Export a grid widget as an Excel sheet. ### Parameters - **target_dir** (str) - Optional - Directory path to store the Excel sheet. - **file_name** (str) - Optional - Name of the Excel file. - **user** (User) - Optional - User object to create timezone-aware datetime values. ### Returns - **str** - File path of the created Excel sheet. ``` -------------------------------- ### Authenticate with the Client Source: https://pykechain.readthedocs.io/en/stable/api/client.html Login to the KE-chain instance using either a user token or basic username/password credentials. ```python >>> client = Client() >>> client.login(token='') ``` ```python >>> client = Client() >>> client.login(username='user', password='pw') ``` ```python >>> client = Client() >>> client.login('username','password') ``` -------------------------------- ### Initialize Widget Metadata and Source Scopes Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widgets_manager.html Configures widget metadata based on provided source parameters and scope types. ```python meta = _initiate_meta(kwargs=kwargs, activity=self.activity) meta, title = _set_title(meta, title=title, **kwargs) if source_scopes_tags: meta.update( { MetaWidget.SOURCE: DashboardWidgetSourceScopes.TAGGED_SCOPES, MetaWidget.SCOPE_TAG: check_type( source_scopes_tags, list, "source_scopes_tags" ), } ) elif source_subprocess: meta.update( { MetaWidget.SOURCE: DashboardWidgetSourceScopes.SUBPROCESS, MetaWidget.SCOPE_TAG: check_type( source_subprocess, list, "source_subprocess" ), } ) elif source_selected_scopes: meta.update( { MetaWidget.SOURCE: DashboardWidgetSourceScopes.SELECTED_SCOPES, MetaWidget.SCOPE_LIST: check_type( source_selected_scopes, list, "source_selected_scopes" ), } ) elif show_forms: meta.update( { MetaWidget.SOURCE: DashboardWidgetSourceScopes.FORMS, } ) else: meta.update( { MetaWidget.SOURCE: check_enum( source_scopes, DashboardWidgetSourceScopes, "source_scopes" ) } ) ``` -------------------------------- ### Retrieve a project from environment variables Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/helpers.html When no parameters are provided, the function automatically attempts to resolve configuration from existing environment variables. ```python >>> env_vars = os.environ >>> env_vars.get('KECHAIN_TOKEN') bd9377793f7e74a29dbb11fce969 >>> env_vars.get('KECHAIN_URL') http://localhost:8080 >>> env_vars.get('KECHAIN_SCOPE') Bike Project >>> project = get_project() >>> project.name Bike Project ``` -------------------------------- ### download_as_pdf() Source: https://pykechain.readthedocs.io/en/stable/api/models_activity.html Retrieve the PDF of the Activity. ```APIDOC ## download_as_pdf(target_dir=None, pdf_filename=None, paper_size='a4paper', paper_orientation='portrait', include_appendices=False, as_zip=False, include_qr_code=False, user=None, timeout=180) ### Description Retrieve the PDF of the Activity. ### Parameters - **target_dir** (str) - Optional - directory path name where the store the log.txt to. - **pdf_filename** (str) - Optional - log filename to write the log to. - **paper_size** (PaperSize) - Optional - The size of the paper (a4paper, a3paper, a2paper, a1paper, a0paper). - **paper_orientation** (PaperOrientation) - Optional - The orientation of the paper (portrait, landscape). - **include_appendices** (bool) - Optional - True if the PDF should contain appendices. - **as_zip** (bool) - Optional - If True, returns a ZIP with attachments. - **include_qr_code** (bool) - Optional - True if the PDF should include a QR-code. - **user** (User) - Optional - Used to calculate the offset needed to interpret Datetime Properties. - **timeout** (int) - Optional - Number of seconds to wait for the PDF to be created. ### Returns Path to the saved pdf file (str). ### Raises - **APIError** - if the pdf file could not be found. - **OSError** - if the file could not be written. ``` -------------------------------- ### Using SideBarManager as a Context Manager Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/sidebar/sidebar_manager.html Demonstrates using the 'with' statement to perform bulk updates to the sidebar, which postpones KE-chain updates until the block exits. ```python >>> with scope.side_bar() as manager: >>> button = manager.add_ke_chain_page(page_name=KEChainPages.EXPLORER) >>> manager.insert(index=0, button=button) ``` -------------------------------- ### Apply Form Transition Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/form.html Executes a transition on a form by building the appropriate API URL and sending a POST request. ```python url = self._client._build_url( "form_apply_transition", form_id=self.id, transition_id=transition.id ) query_params = API_EXTRA_PARAMS.get(self.url_list_name) response = self._client._request( "POST", url=url, params=query_params, ) if response.status_code != requests.codes.ok: raise APIError( "Could not transition the form", response=response, ) self.refresh(json=response.json()["results"][0]) ``` -------------------------------- ### Download Activity as PDF Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/activity.html Exports an activity to a PDF file with configurable paper size, orientation, and appendix settings. ```python def download_as_pdf( self, target_dir: str = None, pdf_filename: str = None, paper_size: PaperSize = PaperSize.A4, paper_orientation: PaperOrientation = PaperOrientation.PORTRAIT, include_appendices: bool = False, as_zip: bool = False, include_qr_code: bool = False, user: Optional[User] = None, timeout: int = ASYNC_TIMEOUT_LIMIT, ) -> str: """ Retrieve the PDF of the Activity. .. versionadded:: 2.1 :param target_dir: (optional) directory path name where the store the log.txt to. :param pdf_filename: (optional) log filename to write the log to, defaults to `log.txt`. :param paper_size: The size of the paper to which the PDF is downloaded: - a4paper (default): A4 paper size - a3paper: A3 paper size - a2paper: A2 paper size - a1paper: A1 paper size - a0paper: A0 paper size :param paper_orientation: The orientation of the paper to which the PDF is downloaded: - portrait (default): portrait orientation - landscape: landscape orientation :param include_appendices: True if the PDF should contain appendices, False (default) if otherwise. :param as_zip: The PDF appendices, if appendices are enabled are rendered inline inside the PDF. If this is set to True, then a ZIP will be returned where all attachments that cannot be rendered, including the PDF attachments are included in that zip in a subdirectory 'attachments'. (defaults to False) :param include_qr_code: True if the PDF should include a QR-code, False (default) if otherwise. :param user: (optional) used to calculate the offset needed to interpret Datetime Properties. Not having a user will simply use the default UTC. :param timeout: (optional) number of seconds to wait for the PDF to be created, defaults to ASYNC_TIMEOUT_LIMIT :raises APIError: if the pdf file could not be found. :raises OSError: if the file could not be written. :returns Path to the saved pdf file :rtype str """ if not pdf_filename: pdf_filename = self.name + ".pdf" if not pdf_filename.endswith(".pdf"): pdf_filename += ".pdf" full_path = os.path.join(target_dir or os.getcwd(), pdf_filename) request_params = dict( papersize=check_enum(paper_size, PaperSize, "paper_size"), orientation=check_enum( paper_orientation, PaperOrientation, "paper_orientation" ), appendices=check_type(include_appendices, bool, "include_appendices"), as_zip=check_type(as_zip, bool, "as_zip"), includeqr=check_type(include_qr_code, bool, "include_qr_code"), ) if user: user_object = check_type(user, User, "user") request_params.update( offset=get_offset_from_user_timezone(user=user_object), timezone=str(get_timezone_from_user(user=user_object)), ) url = self._client._build_url("activity_export", activity_id=self.id) response = self._client._request("GET", url, params=request_params) if response.status_code != requests.codes.ok: # pragma: no cover raise APIError( f"Could not download PDF of Activity {self}", response=response ) # If appendices are included, the request becomes asynchronous if include_appendices: # pragma: no cover data = response.json() # Download the pdf async url = urljoin(self._client.api_root, data["download_url"]) count = 0 while count <= timeout: response = self._client._request("GET", url=url) ``` -------------------------------- ### Copy a Widget to a Target Activity Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widget.html Demonstrates how to copy an existing widget from a source activity to a target activity using the copy method. ```python >>> source_activity = project.activity('Source task') >>> target_activity = project.activity('Target task') >>> widget_manager = source_activity.widgets() >>> widget_to_copy = widget_manager[1] >>> widget_to_copy.copy(target_activity=target_activity, order=3) ``` -------------------------------- ### Configure and Create Dashboard Widget Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widgets_manager.html Logic for processing project scopes and updating widget metadata before creating a new dashboard widget instance. ```python show_projects_list = list() if show_scopes is None: for value in DashboardWidgetShowScopes.values(): show_projects_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowScopes.values().index( value ), MetaWidget.SELECTED: True, } ) else: check_type(show_tasks, list, "show_tasks") for value in DashboardWidgetShowScopes.values(): if value in show_scopes: show_projects_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowScopes.values().index( value ), MetaWidget.SELECTED: True, } ) else: show_projects_list.append( { MetaWidget.NAME: value, MetaWidget.ORDER: DashboardWidgetShowScopes.values().index( value ), MetaWidget.SELECTED: False, } ) meta.update( { MetaWidget.SHOW_NUMBERS: show_tasks_list, MetaWidget.SHOW_NUMBERS_FORMS: show_form_status_list, MetaWidget.SHOW_NUMBERS_PROJECTS: show_projects_list, MetaWidget.NO_BACKGROUND: check_type( no_background, bool, "no_background" ), MetaWidget.SHOW_ASSIGNEES: check_type( show_assignees, bool, "show_assignees" ), MetaWidget.SHOW_ASSIGNEES_TABLE: check_type( show_assignees_table, bool, "show_assignees_table" ), MetaWidget.SHOW_OPEN_TASK_ASSIGNEES: check_type( show_open_task_assignees, bool, "show_open_task_assignees" ), MetaWidget.SHOW_OPEN_VS_CLOSED_TASKS: check_type( show_open_vs_closed_tasks, bool, "show_open_vs_closed_tasks" ), MetaWidget.SHOW_OPEN_VS_CLOSED_TASKS_ASSIGNEES: check_type( show_open_closed_tasks_assignees, bool, "show_open_closed_tasks_assignees", ), MetaWidget.SHOW_FORM_STATUS_PER_ASSIGNEES: check_type( show_form_status_per_assignees, bool, "show_form_status_per_assignees", ), MetaWidget.SHOW_ASSIGNEES_FOR_FORM_STATUSES: check_type( show_assignees_for_form_statuses, bool, "show_assignees_for_form_statuses", ), MetaWidget.SHOW_STATUS_CATEGORY_FORMS: check_type( show_status_category_forms, bool, "show_status_category_forms" ), } ) widget = self.create_widget( widget_type=WidgetTypes.DASHBOARD, meta=meta, title=title, parent=parent_widget, **kwargs, ) return widget ``` -------------------------------- ### Manage Models Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/scope.html Methods for retrieving, creating, and configuring part models within a scope. ```python def model(self, *args, **kwargs) -> "Part": """Retrieve a single model belonging to this scope. See :class:`pykechain.Client.model` for available parameters. """ return self._client.model(*args, scope_id=self.id, **kwargs) ``` ```python def create_model(self, parent, name, multiplicity=Multiplicity.ZERO_MANY) -> "Part": """Create a single part model in this scope. See :class:`pykechain.Client.create_model` for available parameters. """ return self._client.create_model(parent, name, multiplicity=multiplicity) ``` -------------------------------- ### Retrieve a project with direct parameters Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/helpers.html Use this method to explicitly pass credentials and scope information to the function. ```python >>> from pykechain import get_project >>> project = get_project(url='http://localhost:8000', ... username='foo', password='bar', scope='1st!') >>> print(project.name) 1st ``` -------------------------------- ### login(username, password, token) Source: https://pykechain.readthedocs.io/en/stable/api/client.html Authenticates the client session using either username/password or a user token. ```APIDOC ## login(username, password, token) ### Description Login into KE-chain with either username/password or token. ### Parameters - **username** (str) - Optional - Username for your user from KE-chain. - **password** (str) - Optional - Password for your user from KE-chain. - **token** (str) - Optional - User authentication token retrieved from KE-chain. ``` -------------------------------- ### PartSet Class Implementation Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/partset.html The core implementation of the PartSet class, including initialization, iteration, and HTML representation logic. ```python from typing import Iterable, Text # noqa: F401 from pykechain.models.part import Part # noqa: F401 [docs] class PartSet(Iterable): """A set of KE-chain parts. Adding set-like methods on a list of parts: * iterable * len() * get() * iPython notebook support for HTML table """ def __init__(self, parts: Iterable[Part]): """Construct a PartSet from a part iterable.""" self._parts = list(parts) def __repr__(self): # pragma: no cover return f"" def __iter__(self): return iter(self._parts) def __len__(self): return len(self._parts) def __getitem__(self, k: int) -> Part: if isinstance(k, int): return self._parts[k] raise NotImplementedError def _repr_html_(self) -> str: all_instances = all(p.category == "INSTANCE" for p in self._parts) html = ["", "", ""] if not all_instances: html.append("") html.append("") html.append("") for part in self._parts: html.append("") html.append(f"") if not all_instances: html.append(f"") html.append(f"") html.append("") html.append("
PartCategoryID
{part.name}{part.category}{part.id}
") return "".join(html) ``` -------------------------------- ### ServiceExecution Initialization Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/service.html Constructs a ServiceExecution object from JSON data. ```python def __init__(self, json, **kwargs): """Construct a scope from provided json data.""" super().__init__(json, **kwargs) del self.created_at del self.updated_at self.name = json.get("service_name") self.service_id = json.get("service") self.status: ServiceExecutionStatus = json.get("status", "") self.user = json.get("username") if json.get("activity") is not None: self.activity_id: Optional[str] = json["activity"].get("id") else: self.activity_id = None self.started_at: Optional[datetime] = parse_datetime(json.get("started_at")) self.finished_at: Optional[datetime] = parse_datetime(json.get("finished_at")) self._service: Optional[Service] = None ``` -------------------------------- ### Define KEChain Page Labels and Icons Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/enums.html Dictionaries mapping KEChain pages to localized labels, display names, and FontAwesome icons. ```python KEChainPageLabels_nl = { KEChainPages.DETAIL: "Project details", KEChainPages.FORMS: "Formulieren", KEChainPages.TASKS: "Taken", KEChainPages.WORK_BREAKDOWN: "Taakverdeling", KEChainPages.CATALOG_FORMS: "Sjablonen", KEChainPages.CONTEXTS: "Contexten", KEChainPages.WORKFLOWS: "Workflows", KEChainPages.CATALOG_WBS: "Catalogus", KEChainPages.APP_WBS: "App schermen", KEChainPages.DATA_MODEL: "Data model", KEChainPages.EXPLORER: "Explorer", KEChainPages.SERVICES: "Scripts", } ``` ```python CardWidgetKEChainPageLink = { KEChainPages.DETAIL: "Project", KEChainPages.FORMS: "Forms", KEChainPages.TASKS: "Tasks", KEChainPages.DATA_MODEL: "Model", KEChainPages.EXPLORER: "Explorer", KEChainPages.SERVICES: "Script", KEChainPages.WORK_BREAKDOWN: "Work Breakdown", KEChainPages.CATALOG_WBS: "Catalog Tasks", KEChainPages.APP_WBS: "App Tasks", KEChainPages.CATALOG_FORMS: "Template Forms", KEChainPages.CONTEXTS: "Contexts", KEChainPages.WORKFLOWS: "Workflows", } ``` ```python KEChainPageIcons = { KEChainPages.DETAIL: "bookmark", KEChainPages.FORMS: "file-contract", KEChainPages.TASKS: "edit", KEChainPages.WORK_BREAKDOWN: "sitemap", KEChainPages.CATALOG_FORMS: "file-export", KEChainPages.CONTEXTS: "tags", KEChainPages.WORKFLOWS: "directions", KEChainPages.CATALOG_WBS: "books", KEChainPages.APP_WBS: "tablet-alt", KEChainPages.DATA_MODEL: "cube", KEChainPages.EXPLORER: "folder", KEChainPages.SERVICES: "file-code", } ``` -------------------------------- ### Add a Notebook Widget Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/widgets/widgets_manager.html Adds a KE-chain Notebook widget to the WidgetManager, requiring a Service object or UUID. ```python def add_notebook_widget( self, notebook: "Service", title: TITLE_TYPING = False, parent_widget: Optional[Union[Widget, str]] = None, **kwargs, ) -> Widget: """ Add a KE-chain Notebook (e.g. notebook widget) to the WidgetManager. The widget will be saved to KE-chain. :param notebook: The Notebook to which the button will be coupled and will start when the button is pressed. :type notebook: :class:`Service` or UUID :param title: A custom title for the notebook widget * False (default): Notebook name * String value: Custom title * None: No title :type title: bool or basestring or None :param parent_widget: (O) parent of the widget for Multicolumn and Multirow widget. :type parent_widget: Widget or basestring or None :param kwargs: additional keyword arguments to pass :return: newly created widget :rtype: Widget :raises IllegalArgumentError: when incorrect arguments are provided :raises APIError: When the widget could not be created. """ from pykechain.models import Service if isinstance(notebook, Service): notebook_id = notebook.id elif isinstance(notebook, str) and is_uuid(notebook): notebook_id = notebook notebook = self._client.service(id=notebook_id) else: raise IllegalArgumentError( "When using the add_notebook_widget, notebook must be a Service or Service id. " "Type is: {}".format(type(notebook)) ) meta = _initiate_meta(kwargs=kwargs, activity=self.activity) meta, title = _set_title(meta, title=title, **kwargs) meta.update({AssociatedObjectId.SERVICE_ID: notebook_id}) widget = self.create_widget( widget_type=WidgetTypes.NOTEBOOK, title=title, meta=meta, parent=parent_widget, **kwargs, ) return widget ``` -------------------------------- ### Retrieve Scope Members Source: https://pykechain.readthedocs.io/en/stable/_modules/pykechain/models/scope.html Demonstrates how to fetch members from a project scope, with optional filtering by role. ```python >>> members = project.members() >>> managers = project.members(is_manager=True) >>> supervisors = project.members(is_supervisor=True) >>> leadmembers = project.members(is_leadmember=True) ```