# Developing Python Applications

MicroStation is delivered with a python interpreter. See - [API Versions](../apiversions), for reference to this version and the libraries included in the installation. This is sufficient to run any python library function within the MicroStation environment and also ensures that scripts can be debugged using Visual Studio Code.

## MicroStation Keyin Command Support 

Python applications can register keyins within MicroStation similar to C++ and C#-AddIn's which will on entering the specified keyin execute a function in python. The pattern to do this is the same as it is for C# defining a commands.xml file with the keyin table in it and specifying the function to call in the "KeyInHandler" xml node. The xml file format is well documented in the following link [Adding Commands to Add-ins](https://bentleysystems.service-now.com/community?id=kb_article_view&sysparm_article=KB0012761).  There is a PythonKeyinManager class provided which contains an API LoadCommandTableFromXml to register the command table with MicroStation. There is an example of this  in the ItemTypeCustomProperty.py example. Below is the code from that

```python
    keyinXml = os.path.dirname(__file__) + '/ItemTypeCustom.commands.xml'
    PythonKeyinManager.GetManager ().LoadCommandTableFromXml (WString (__file__), WString (keyinXml))    
```
The first argument is the full path of the python file to register the keyins for and the second argument is the full path of the keyins.xml file. Note: The python filename has to be unique within the scope of all the python files loaded into MicroStation in order for the keyins to work. Also there are no arguments to the function tied to the keyin, but you can retrieve the arguments to the command through sys.argv list.

```python

def myCommandFn():
    print (len(sys.argv))
    if (len(sys.argv) > 0)
        print (sys.argv[0])

```
MicroStation also captures the global python state for each python file which registers keyins, as such its possible to declare global variables in your python file and have them persist between the execution of individual keyins



## Using Other Libraries

Part of the power of the Python language is the many and varied libraries which can be installed and used with the language. In order to use other libraries with MicroStation Python, it will be necessary to install the Python interpreter separately from MicroStation and enable MicroStation to reference that interpreter. The reason for this is for security reasons and ensuring the integrity of the MicroStation Installation.

It is essential that the version of Python installed matches the version specified in [API Versions](../apiversions). This is the version that the MicroStation API's are built, linked and tested against. 
Then the users MicroStation instance will need to set the ```MS_PYTHON``` configuration variable to the location of the root python directory. This will make sure that this version of python is the first found by MicroStation when searching for the python portable executable files. Additional libraries which are required for running scripts can then be installed in the usual way with pip.

Also users should ensure that the PATH environment variable does not point to another installation of Python in its list prior to that of MicroStation. The Python interpreter which will run when using MicroStation will always be the first found in the PATH environment variable, this is a feature of the language.

## Python Virtual Environments

A typical workflow for performing your own package management on a base version of Python is to create a Python virtual environment. What creating a virtual environment does is copy a set of the python installation into your virtual environment directory and then prepend the system PATH environment variable with the path to your virtual environment "Scripts" directory. As such when looking for a package, the virtual environment path is looked at first, then the original python installation path is looked at. Setting up this process for MicroStation will not work correctly as the   ```MS_PYTHON``` variable will only take a single path. Please see the section above, if you want to manage your own packages, install the same python version into a separate directory on your computer then install the required packages there and set the ```MS_PYTHON``` variable to point to it.

## Multithreading

MicroStation's Python libraries are only available for use within the main Python thread, calling MicroStation API's from other threads, will result in undetermined behavior and destabilize the product.

## Deploying Python Scripts

When deploying a python file to a user, if only the python libraries delivered with MicroStation are used, then all that the user needs is the .py file and to run it in the python manager in MicroStation. If other additional libraries are required as explained above it would be necessary for the user to install Python and install the additional libraries along with it.

## MicroStation High Security Mode

Currently running Python scripts when MicroStation is running in high security mode is not available we are continuing to investigate this area.
