Zum Hauptinhalt gehen

Run Python Activity - Basic Example Needed

Kommentare

17 Kommentare

  • Tom Neer

    Matt,

     

    I actually have a demo that is on my todo list to post a blog on when I get a few fires put out. But you should be able to piece together what we are doing.

     

    This is a script to pull environment variables from a server and uses Python to return value requested. It comes in 3 pieces but does what you are after. Ask any questions and Zack or myself will try to respond.

     

    Client Workflow (use "Open by URL" to copy)

    https://www.arcgis.com/home/item.html?id=6520b63d0ebd40449ed805c2048470e4

     

    Server Workflow (use "Open by URL" to copy)

    https://www.arcgis.com/home/item.html?id=e4bfbfbf2ebe4b76815804345ae750cc

     

    Python Script:

    """ Title: Get OS Environment Variables   Description: Quick script that takes a list of os environment variable keys and returns a JSON string of the key:value pairs. If a variable does not exist, "ERROR: OS Variable not found." is returned.   Requires: Written in Python 3.7.3 but should work in all current versions of Python.   :ORGANIZATION: geoWidgets by Digital Data Services, Inc. :CONTACT: https://www.geowidgets.io :UPDATED: 2019-06-24 """   from json import dumps from os import environ from sys import argv     def main(env_variables): # Skip first argv, which is the script source keys = env_variables[1:]   # Set keys that the server is allowed to return blacklisted_keys = [] # Blacklist has precedence over whitelist whitelisted_keys = ['TEMP', 'TMP', 'geowidgets_demo', 'USERNAME', 'password', 'windir'] """ Takes a list of keys and searches for then in the OS environment variables. Returns a JSON formatted string of keys and values.   :param keys: String list of OS environment variables :return: JSON string of key:value pairs """ use_whitelist = len(whitelisted_keys) > 0 env_dict = {} for key in keys: if (key not in environ) or (key in blacklisted_keys) or (use_whitelist and key not in whitelisted_keys): # Withhold secret keys, provide same message for secrets and novalues to be sneaky env_dict[key] = 'ERROR: No OS variable "%s" found.' % key else: # Add environment to output dictionary env_dict[key] = environ[key] return dumps(env_dict)     if __name__ == '__main__': main(env_variables)

    We recommend storing the Python script in C:\ProgramData\Geocortex\Workflow\PythonScripts\getOSEnvirons.py and don't forget your permissions.

     

    We hope to have this written up as a tutorial blog post sometime this month.

     

    Best,

    -Tom

     

     

     

    0
  • Matt Palavido

    Tom,

     

    Thanks for the very quick response! Would you be able to export the server side workflow as a JSON file? When trying to copy from a URL, designer assumes that it is a client side workflow and strips out or replaces the server side tools (see screenshot) with client side tools (i.e. run workflow instead of run python). At least I think that is what is happening :)

     

    Thanks again!

     

    Matt

     

    workflow

     

     

    0
  • Tom Neer

    Guess that is good and bad. Here's the json formatted:

    { "components": [{ "steps": [{ "inputs": {}, "transitions": [{ "inputs": {}, "id": 5, "target": { "id": 6 }, "position": "90,60 90,140" } ], "id": 3, "purpose": "start", "title": "Start", "position": "0,0" }, { "inputs": { "pythonFile": "C:\\ProgramData\\Geocortex\\Workflow\\PythonScripts\\getOSEnvirons.py", "arguments": { "accessors": ["$inputs"], "annotations": [{ "kind": "idref", "index": 0, "count": 7 } ], "code": "$inputs.inputs.variableNames.join(' ')", "source": "$inputs.inputs.variableNames.join(' ')" } }, "transitions": [{ "inputs": {}, "id": 12, "target": { "id": 17 }, "position": "90,420 90,460", "sourceConnector": "bottom" } ], "id": 4, "action": "gcx:wf:server::RunPython", "description": "Run server script that returns dictionary of system environment variables", "position": "-30,290", "title": "Run Python Script", "name": "runPython" }, { "inputs": { "json": { "accessors": ["$runPython"], "annotations": [{ "kind": "idref", "index": 0, "count": 10 } ], "code": "$runPython.result", "source": "$runPython.result" } }, "transitions": [{ "inputs": {}, "id": 18, "target": { "id": 8 }, "position": "90,530 90,570", "sourceConnector": "bottom" } ], "id": 17, "action": "gcx:wf:core::ParseJson", "position": "-30,460", "title": "Parse JSON to Object", "name": "scriptOutput" }, { "inputs": { "name": "success", "value": { "accessors": ["$runPython"], "annotations": [{ "kind": "idref", "index": 1, "count": 10 } ], "code": "$runPython.success", "source": " $runPython.success" } }, "transitions": [{ "inputs": {}, "id": 15, "target": { "id": 14 }, "position": "90,600 90,630", "sourceConnector": "bottom" } ], "id": 8, "action": "gcx:wf:core::SetWorkflowOutput", "position": "-30,570", "title": "Set Success Output" }, { "inputs": { "name": "OSVariables", "value": { "accessors": ["$scriptOutput"], "annotations": [{ "kind": "idref", "index": 0, "count": 13 } ], "code": "$scriptOutput.result", "source": "$scriptOutput.result" } }, "id": 14, "action": "gcx:wf:core::SetWorkflowOutput", "position": "-30,630", "title": "Set Values Output", "description": "" }, { "inputs": {}, "transitions": [{ "inputs": {}, "id": 7, "target": { "id": 4 }, "position": "90,250 90,290", "sourceConnector": "bottom", "targetConnector": "top" } ], "id": 6, "action": "gcx:wf:core::GetWorkflowInputs", "position": "-30,140", "title": "Get Workflow Inputs", "description": "\"variableNames\" are sent as args to python script", "name": "inputs" } ], "id": 2 } ], "designerVersion": "5.11.0+28", "start": { "id": 3 } }

     

    0
  • Matt Palavido

    Tom,

     

    Perfect! That worked. Thanks again for the example. This helps me tremendously.

     

    Matt

     

    serverworkflow

    0
  • Tom Neer

    Glad we could help.

     

    The Open by URL of server workflows could be better handled (maybe even some text saying it only works for client-side workflows). It should probably just post a dialog saying it cannot import the workflow rather than randomly replacing Activities. Unfortunately, I don't see a key:value that would differentiate between a client or server workflow.

    0
  • Permanently deleted user

    Hi @Tom Neer? . I am trying to do this exact thing, but I am not getting any results. I found a thread that in order for the python to run, I needed to set the identity of the GeocortexWorkflow application pool to the local admin, which I have, but it is still not working. Could you help please?

    0
  • Tom Neer

    @Linda Stewart? We actually do not recommend using a local admin for the GeocortexWorkflow app pool. It is a huge security hole.

     

    We scratched our head for sometime on this one. It's not well documented. What works for us is to assign permissions to the GeocortexWorkflow app pool to the document. This is a bit tricky. You can't search for this account.

     

    1. Right-click on the file you want to give Workflow access to and select Properties
    2. Select the Security tab and click on Edit
    3. In the Permissions dialog, click Add
    4. In the Select Users [...] dialog:
      1. Make sure that your Location is set to you local server, not an AD controller
      2. Enter "IIS AppPool\GeocortexWorkflow" into the Object Name text field and click Check Names. This should change to GeocortexWorkflow (underlined), if you did it correctly.
      3. Click OK
    5. Assign your permissions as appropriate for your application.

     

    Hope that helps.

     

    Best

    -Tom

    0
  • Permanently deleted user

    Thanks @Tom Neer . Still doesn't work for me.  It doesn't run the python, the JobResult.success is false. Is there anything else I should check or change? Thank you!

    0
  • Permanently deleted user

    Also, I'm seeing the same errors as this thread https://communities.geocortex.com/s/question/0D5f200006YXWC4CAP/server-workflow-the-ticket-is-not-valid , but I checked and the workflow is not referencing itself. Not sure if the issue is in accessing the server workflow or the python in the server workflow

    0
  • Zack Robison

    That error sounds like the issue is access to the server workflow... but then I wouldn't expect you to see any JobResult from the python activity so this is confusing. Perhaps it belies a permissions issue with your python file? We have found that keeping the python scripts in the ":\ProgramData\Geocortex\Workflow\" directory to be helpful with this.

    0
  • Permanently deleted user

    I have tried these things, but all have failed.

    • placed python in "c:\programdata\geocortex\workflow\pythonscripts" and added GeocortexWorkflow appPool to the security of the python script
    • placed python in a shared folder on the server "\\<serverName>\<sharedFolder>\scripts\" 
    • specified admin as the identity on the geocortexWorkflow appPool (I know it's not recommended, but I wanted to see if it will work -- it didn't)

     

    If the issue is accessing the python, is there a way for me to positively test that? if it's just the server workflow itself, is there a way to test that?

     

    0
  • Matt Palavido

    I had to modify one more IIS setting to get mine to work correctly. Under the advanced settings for the Workflow application pool, I had to set 'Load Profile' to true.

     

    iis

    0
  • Permanently deleted user

    ?I was so hopeful! Thank you @Matt Palavido?, but that did not fix it for me. 

    I'm assuming there are 3 points of possible failure.

    1. That the client workflow cannot access the server workflow
    2. that the server workflow cannot access the server
    3. that the python is not being executed

    I created another server workflow that has the copy file activity. After running the client side workflow to call the server workflow, I checked the new location and the file is copied which means there is not a problem with scenarios 1 & 2. So does that mean it was a problem with scenario 3?

    There is python2.7 and 3.6 on the server so maybe it doesn't know which to use to execute the python? The code is so simple, I would not think it would matter which version is used.

    But the "success" outputs is false which tells me the python did run but had issues?

     

    0
  • Permanently deleted user

    So I sent a support case to Latitude about my issue and they are saying it's a bug.

    Bug: 26675. Not sure from my issue or this was already an identified bug. ?

    0
  • Permanently deleted user

    @Linda Stewart? You can still call Workflow 4 and use the scripting in there.

    0
  • Permanently deleted user

    @DDS Technical Support? I created a workflow 4 and put in a very simple c# script to call a batch file. it didn't throw any errors, but also didn't do anything, certainly did not invoke the batch file. Do you have any advice on how to make this work??

    0
  • Peter Haddrill

    Got this working based on Tom's initial comment above, with the python script re-formatted below. But grabbed the Server workflow json from Tom's comment here and imported into wf designer. Didnt use the server wf from initial comment (agol item url), has no Run Python activity in it. Used wf designer on a local pc, version 5.29.0, and storing items in arcgis online. 

    """ Title: Get OS Environment Variables
    Description: Quick script that takes a list of os environment variable keys and returns a JSON string of the key:value pairs.
    If a variable does not exist, "ERROR: OS Variable not found." is returned.
    Requires: Written in Python 3.7.3 but should work in all current versions of Python.
    :ORGANIZATION: geoWidgets by Digital Data Services, Inc. :CONTACT: https://www.geowidgets.io :UPDATED: 2019-06-24 """
    from json import dumps
    from os import environ
    from sys import argv

    def main(env_variables):
        # Skip first argv, which is the script source
        keys = env_variables[1:]
        # Set keys that the server is allowed to return
        denylisted_keys = []
        # Denylist has precedence over allowlist
        allowlisted_keys = ['TEMP', 'TMP', 'geowidgets_demo', 'USERNAME', 'password', 'windir']
        """ Takes a list of keys and searches for then in the OS environment variables. Returns a JSON formatted string of keys and values.   :param keys: String list of OS environment variables :return: JSON string of key:value pairs """
        use_allowlist = len(allowlisted_keys) > 0
        env_dict = {}
        for key in keys:
            if (key not in environ) or (key in denylisted_keys) or (use_allowlist and key not in allowlisted_keys):
                # Withhold secret keys, provide same message for secrets and novalues to be sneaky
                env_dict[key] = 'ERROR: No OS variable "%s" found.' % key
            else:
                # Add environment to output dictionary
                env_dict[key] = environ[key]
                return dumps(env_dict)

    if __name__ == '__main__':
        main(env_variables)

    0

Bitte melden Sie sich an, um einen Kommentar zu hinterlassen.