Package: orionpy
OrionpyThe OrionPy API allows to manage and administrate Orion without having to use the arcOpole Builder console.OrionpyInstallation requirementsWhich python modules are required for this project ?InstallationUsageJupyter exampleConnection to OrionGet access to the dataWorking with filtersGroups managementResource handlingChanging rightsHandling Cadastre resourceIMC handlingCSV HandlingHandling Stats resourceHandling projects and geonotesWorking with the ArcGIS API for Python.Go furtherInstallation requirementsFirst of all, you need to havePythoninstalled, with a version >= 3.7.It is then required to installpip.For information, pip is already installed if you are using Python 2 >=2.7.9 or Python 3 >=3.4 downloaded fromhttps://www.python.org/.
It is also already installed if you are working in a Virtual Environment created by virtualenv or pyvenv.Just make sure to upgrade pip.Which python modules are required for this project ?The packages that will be installed in the following steps are :requestsurllib3InstallationSinceOrionPyis available onhttps://pypi.org/project/orionpy/, it must be installed using :pipinstallorionpyUsageThe following section describes the main functions available in the API.Jupyter exampleThere is a full and executable example of OrionPy's usage in the fileDemonstration.ipynb.This file can be found in the project'shomepage)
and opened usingJupyter.For more information on Jupyter, how to install it and use it, check the following links:http://jupyter.org/https://developers.arcgis.com/python/guide/using-the-jupyter-notebook-environment/https://developers.arcgis.com/python/guide/install-and-set-up/#Test-your-install-with-jupyter-notebookOf course, you can also test the API without Jupyter.
Just note that the examples in this README might not work being "copy-and-pasted" in a Python file.Other examples of code using the API can be found in themain.pyfile.Connection to OrionOrion is our main class.
It is by using its instance that the user has access to all data and operations available.This Orion class generates a token authorizing the user connection to the Orion server.Here is an example connecting tohttps://front.arcopole.fr:fromorionpy.orioncore.OrionimportOrionusername=""# Enter here the login for the arcOpole Builder console.password=""# If empty, will be asked - securely - later.url_machine="https://front.arcopole.fr"# External url of the WebAdaptor.portal="portal"# Entry point to the WebAdaptor of the Portal for ArcGIS. (optional. default = "portal")orion=Orion(username,password,url_machine,portal)To create Orion session, the user must be an arcOpole administrator. In case of it is necessary to use some Orion functionnalities with an other user. It is possible to create a light Orion session as follow. In that case, all manage functionnalities are not available :orion=OrionRest(username,password,url_machine,portal)In the case where there is a problem with SSL verification, the parameterverify_certcan be set as follow :orion=Orion(username,password,url_machine,portal,verify_cert=False)It is recommended to leave password as an empty string.
If left empty, a message will be displayed, asking to type down the username's password.Get access to the dataOnce the connection is done, it is possible to get access to the data.Two methods are used for this.
One to get all the elements and another to get one element using its name/id.
WARNING : {elements} must be replaced by one of the following :groups,filters,services.# Get the list of elementselements_list=orion.{elements}.all()# print this listforelementinelements_list:print(element)# Get a particular element and print itelement=orion.{elements}.get(element_name)print(element)For instance, to get (and print) the group "Groupe 2" :group=orion.groups.get("Groupe 2")print(group)Working with filtersTo apply accurate and specific rights, data filters are essentials.Currently, two types of data filters exist : FDU filters and SQL filters.Get the list of all the filters defined or of a particular filter:filters=orion.filters.all()filter=orion.filters.get(filter_name)Create a new FDU filter :# Create a FDU filter on one field :orion.filters.add_FDU_filter(filter_name,fields=[field],filtering_values=['val1','val2',...])# Create a FDU filter on several fields :orion.filters.add_FDU_filter(filter_name,fields=[field1,field2],filtering_values=[['val11','val21'],['val12','val22']])# Create a User FDU filter on one field :properties={"type":"user"#declare filter as a user filter,}orion.filters.add_FDU_filter(filter_name,fields=[field],properties=properties,filtering_values=['val1','val2',...])Create a new SQL filter :# Example creation of a SQL filterorion.filters.add_SQL_filter(filter_name,where_clause="NOMCOMM='NICE'")Removing an existing filter :orion.filters.remove_filter(filter_name)FDU filterIf the filter is of FDU type, some more operations are available such as :# Print all fdu filters :forfdu_finorion.filters.all_fdu():print(fdu_f)# Get fields concerned by the filterfields=fdu_filter.get_fields()# Get all labels corresponding to the defined filtering valueslabels=fdu_filter.get_labels()# Know if a given label is defined :fdu_filter.is_label_defined(label)Update a filter's valueFrom orion.filters, it is possible to update a given filter's values.Update SQL Filterwhere_clauseparameter is a string that contains the filter's condition :"territoire in ('1')"# Updates the where clause on a SQL filter.orion.filters.update_sql_filter_value(filter_name,where_clause)Update FDU FilterTo update FDU filter, need to use an array infiltering_valueslike :["Filter value 1","Filter value 2"]# Replace all FDU values by the new input filtering valuesorion.filters.replace_fdu_values(filter_name,filtering_values)# Adds new filtering values to a FDUorion.filters.add_values_to_fdu(filter_name,filtering_values)# Removes filtering values from a FDUorion.filters.remove_values_from_fdu(filter_name,filtering_values)NB: filtering_values is formatted the same way as inorion.filters.add_FDU_filter.Groups managementIn arcOpole Builder, rights are mainly applied on groups. A group is composed of several users.
Get the list of all groups / a particular group:groups=orion.groups.all()group=orion.groups.get(group_name)group=orion.groups.get_with_id(group_id)Update/Add a FDU's filtering values for this group :fdu_filter=orion.filters.get(filter_name)filter_values=['val1','val2']group.set_filter_values(fdu_filter,filter_values)# 2nd solution if want to set all filtering valuesgroup.set_filter_values(fdu_filter,add_all_values=True)# Other solution if doesn't use labels but field_values :field_values=['field_val1','field_val2','field_val3']field=""# Field corresponding to field valuesgroup.set_filter_field_values(fdu_filter,field_values,field)Update/Add several FDU's filtering values for this group :filter1_name=""# Filter namefilter2_name=""# Filter namefilter1=orion.filters.get(filter1_name)filter2=orion.filters.get(filter2_name)filters_values={filter1:['val1','val2'],filter2:['val3','val4']}group.set_several_filter_values(filters_values)Check if a group already have defined filtering values on a given filter:ifgroup.has_defined_filter_values(fdu_filter):print('This group has defined filtering values')Redefine all FDU's filtering values for this group :group.reset_all_filters_values(filters_values)Users managementIn arcOpole Builder, stats are applied on users.Get the list of all users / a particular user:users=orion.users.all()user=orion.users.get(user_name)user=orion.users.get_with_id(user_id)Resource handlingTypes of resource handled in this API :serviceslayersfieldstablesfieldsServicesGet the list of all ArcGIS services :services=orion.services.all()To get 1 particular ArcGIS service, it is required to use its REST relative Url, which is formatted as :FOLDER/SERVICE_SERVICETYPE.For instance :service=orion.services.get("Cannes/EspacesVerts_FeatureServer")# Get all services' REST urlsurls=orion.services.urls()Get only the services managed by arcOpole Builder (or 1 service in this list) :services=orion.services.all_managed()service=orion.services.get_in_managed(service_rest_url)Enable or Disable service management:service.enable()service.disable()It is also possible to know if a given service is a cadastre resource.
If that is the case, the usual right-handling methods won't be available for this service.ifservice.is_cadastre_resource():print("The service is a cadastre resource")LayersGet all layers or 1 layer from a specific service.In a same service, two layers can have the same name.
Therefore, it is more recommended to use theget_with_idmethod.layers=service.layers.all()layer=service.layers.get_with_id(layer_id)# Not recommended for layers.layer=service.layers.get(layer_name)Get a layer's id :layer_id=service.layers.get_id(layer_name)Group of layersAs a "subtype" of layer, it is also possible to find groups of layers.
In OrionPy, they are handled in the classLayerusing several methods.# If the layer is a group of layers...iflayer.is_group():print('Layer is a group of layers')iflayer.has_sub_layers():# The following methods get a list with IDs of layers in this groupsub_layers_ids=layer.get_sub_layers_ids()print('Layers contained in this group have ids : ',sub_layers_ids)else:print('Layer is not a group of layer')iflayer.has_parent_layer():# If the layer is in a group of layersprint("layer's parent id is :",layer.get_parent_layer_id())TablesAccess to tables (all of them or a specific one) :tables=service.tables.all()table=service.tables.get(table_name)FieldsIt is possible to get access to fields using a layer or a table.Get all / 1 field(s) for a specific layer or a specific table :fields=layer_or_table.fields.all()field=layer_or_table.fields.get(field_name)Get a field's name :name=field.get_name()Changing rightsOnce you've had your resource (service, layer, table or field), it is possible to apply the following operations :Print a right summary :Print a summary of the rights defined on a resource, also the filters applied and if the right is inherited or not.service.print_rights(group)Inheritance handlingEnable/disable right inheritance for a resource and a particular group :service.enable_inheritance(group)service.disable_inheritance(group)ifservice.has_inherited_right(group):print('Resource right is inherited for this group')Clear all rightsFrom aOB 1.3.4, it is possible to clear all rights on a given resources and its sub-resources.
Basically, it does the same as manually enabling inheritance for all profiles on a resource and its sub-resources.service.clear_all_rights()Handling right levelUpdate right-level for a group on a resource :fromorionpy.orioncore.resources.ResourceimportRightLevelright_level=RightLevel.[ACCESS|READ|WRITE]# Pick one of the three rights you want to applyservice.update_right(group,right_level)Note that it is not possible to update right if (between else), the right is inherited or the service is not enabled.If you know what you are doing, you can also use theforce_rightscommand.
This method will automatically disable inheritance and enable service management before updating rights.service.force_right(group,right_level)Apply a filterThe arcOpole Builder console handles the application of a FDU filter on three types of resources :Service,Table,Layer.As an example, here is how to (de)activate a FDU filter on a service for a group# Get the data requiredfdu_filter=orion.filters.get(filter_name)group=orion.groups.get(group_name)service=orion.services.get(service_name)# Activate and/or deactivate a fduservice.activate_fdu_filter(group,fdu_filter)service.deactivate_fdu_filter(group,fdu_filter)It is also possible to (de)activate a SQL filter on layer or table :# Get the data requiredsql_filter=orion.filters.get(filter_name)group=orion.groups.get(group_name)service=orion.services.get(service_name)layer=service.layers.get(layer_name)# Activate and/or deactivate a sql filterlayer.activate_sql_filter(group,sql_filter)layer.deactivate_sql_filter(group,sql_filter)Handling Cadastre resourceYou can get the cadastre resource with# Get the data requiredcadastre_resource=orion.businesses.get_cadastre_resource()Get the filter associated with a Cadastre resourceAfter the cadastre resource is recovered, you can access to the associated filter's id using theassociated_filter_idproperty.If you want to update this filter's filtering value, you must get the corresponding filter.
It is necessary for others methods such asupdate_right(if update toNOMINATIF_ACCESS),activate_filteranddeactivate_filter.To access this filter directly from the Cadastre resource, you must first set it.
It will then be possible to access it using theassociated_filterproperty.# Get the filter associated with the resource's :filter=orion.filters.get_with_id(cadastre_resource.associated_filter_id)cadastre_resource.init_filter_access(filter)#... It is now possible to call methods directly on :cadastre_resource.associated_filterUsing filter with Cadastre resourceAny FDU filter method can be used withassociated_filter.
Moreover, you can call specific method with the Cadastre resource.Reminder : youmustcall theinit_filter_accessmethod before calling theseAlso note thatdeactivate_filterwill not work if the group has a NOMINATIF_ACCESScadastre_resource.activate_filter(group)cadastre_resource.deactivate_filter(group)Managing Cadastre resourceOn the cadastre resource, three rights are available and can be updated usingupdate_rightmethod.
The right levels available are :RightLevel.NO_ACCESSRightLevel.PUBLIC_ACCESSRightLevel.NOMINATIF_ACCESSNote : When switching toRightLevel.NOMINATIF_ACCESSfor a group, the filter must be activated for this group.
Ifinit_filter_accesswas called before,update_rightwill automatically apply the filter# (... get a group to update right for ...)# update the rightscadastre_resource.update_right(group,RightLevel.***)# replace *** by one of the 3 rights applicable# print the rights defined for the group on the cadastre_resourcecadastre_resource.print_rights(group)IMC handlingOrionPy allows to get IMC definition and execute it. All capabilities are available inimcsmodule. The IMC is an object with anid, adescriptionand adefinition# List all IMCsimcs=orion.imcs.all()forimcinimcs:print(imc)# Get IMC by nameimc=orion.imcs.get(name)# Get IMC definitionimc_definition=imc.definitionTo execute an IMC with Orion, you must supply 2 parameters.The first parameter is the IMC definition. The definition can come from the object as define above or it is possible to store definition in json fileThe second parameter is the input geometry. This data can be generated with the REST services of ArcGIS Server and the query operation on layer. It is necessary the query JSON response.After that, it is possible to execute IMC as follow:# Get input parametersdefinition=orion.imcs.get("Info cadastrales").definitionwithopen('query_result.json')asjson_file:input_set=json.load(json_file)# Execute IMCresult=orion.imcs.execute(definition,input_geometry)print(result)CSV HandlingIt is also possible to generate a CSV containing a summary on the current system rights.Several CSV classes exists. Each of them with two methods.
Thegeneratemethod generating a CSV with information.
And theread_and_applymethod reading a CSV file generated and applying modification to the server.Handling filtering values with a CSVThis is done creating aCSVFilteringValuesclass.fromorionpy.orioncsv.csvfilteringvaluesimportCSVFilteringValues# Creates the class to create/handle a csv for filtering values.csv_handler=CSVFilteringValues(orion)csv_path="my_csv.csv"# Enter here a csv filenamecsv_handler.generate(csv_path)### Now you can open the csv file analyze its content and modify it...# To apply modifications written in CSV file :csv_handler.read_and_apply(csv_path)Sample of the CSV generated :FilterLabelGroup1Group2...filter1label110...filter1label200...filter2label111..................0 means that the filtering value is not activated for this group,1 means that it is.Handling rights on a resource with a CSVThis is done creating aCSVRightsManagementclass.It will create a summary of rights on a Service and all of its component (layers, fields, tables).fromorionpy.orioncsv.csvrightsmanagementimportCSVRightsManagement# Creates the class to create/handle a csv for filtering values.csv_handler=CSVRightsManagement(orion)csv_path=""# TODO : Enter here a csv filenameservice_url=""# TODO : Enter here a valid service's rest urlservice=orion.services.get(service_url)group_name=""# TODO enter here a group namegroup_list=[orion.groups.get(group_name)]# NB : The following line might not work directly, please refercsv_handler.generate(csv_path,service,group_list=group_list)### Now you can open the csv file analyze its content and modify it...# To apply modifications written in CSV file :csv_handler.read_and_apply(csv_path)If thegroup_listargument isn't set, thegeneratemethod will get the groups shared with the Service given to generate a summary of rights for all these groups.In order to use this functionnality of getting the groups shared, your orion instance must be of OrionGIS type. (refer to section "Working with the ArcGIS API for Python")csv_handler.generate(csv_path,service)Sample of the CSV generated :TypeRelative urlLabelGroup1Group2...SERVICEServ1_MapServerServ1_MapServerreadaccess...LAYERServ1_MapServer/0layer1inherited (read)write...FIELDServ1_MapServer/0/field1field1accessinherited (write)...FIELDServ1_MapServer/0/field2field2inherited (read)access...SERVICEServ2_FeatureServerServ2_FeatureServerinherited (read)write.....................Importing rights from a JSON fileThis can be made using theCSVFilteringCadastreclass.First, the class must be initialized with a connection to Orion :fromsrc.orioncsv.csvfilteringcadastreimportCSVFilteringCadastrecsv_filtering_cadastre=CSVFilteringCadastre(orion)Then, a CSV file must be generated from the json file, containing data :csv_path=""# TODO : Enter here the csv pathjson_path=""# TODO : Enter here the json file's pathcsv_filtering_cadastre.generate(csv_path,json_path)Once the CSV is generated by analyzing the json, the rights can be imported :csv_filtering_cadastre.read_and_apply(csv_path)Handling Stats resourceStats resource allows to group users in specific organisationnal units. Organizational units represent the administrative division of your organization. One user can only associate with one organisationnal unit.You can get the stats resource with# Get the data requiredstats_resource=orion.businesses.get_stats_resource("hosted")storage_idis an optional parameter to found a specific storage in stats resource. Actuallyhostedis the only available type of storage.
This method return the specificStorageResourceobject. If not foundget_stats_resourcereturn None.Stats resource works with the units organisationnal.  with a specific FDU in arcOpole Builder. After creation, apply one value of this FDU on userFDU for statsIn arcOpole Builder, organisationnal units are modelized by the FDU. So you need to create new FDU with all division of your organisation.It is possible to use FDU with OrionPy or in aob-admin application.For more information on FDU in OrionPy, please refere on FDU creation describe above.# Create FDUorion.filters.add_FDU_filter(filter_stats_name,fields=fields,filtering_values=values)Example for filtering_values : ['Secteur1', 'Secteur2', ...](Dis)associate FDU with storage resourceTo associate FDU with storage resource useupdate_filtermethod.To disassociate it, usedisassociate_filtermethod.# Associate filter to storage resourcestorage_resource.update_filter(fdu_filter.get_id())# Disassociate the filter from the storage resourcestorage_resource.disassociate_filter()Add filter value to userAfter create specific stats FDU, associate FDU to storage resource, the last step is to add filter value for users. In stats module, one user only can associate one filter value.# Add filter value to a specific userfilter_values=['Secteur1']user.set_filter_values(fdu_filter,filter_values)Handling organisationnal units with a CSVThis is done creating aCSVOrganisationUnitclass.It will create a summary of users and there associated organisationnal units.fromorionpy.orioncsv.csvorganisationunitimportCSVOrganisationUnit# Creates the class to create/handle a csv for filtering values.csv_handler=CSVOrganisationUnit(orion)csv_path=""# TODO : Enter here a csv filename# To generate a csv file that will list the users and their associated organizational unitcsv_handler.generate(csv_path)### Now you can open the csv file analyze its content and modify it...# To apply modifications written in CSV file :csv_handler.read_and_apply(csv_path)Sample for CSVUserNameOrganizationadmin_aobSecteur1user1Secteur2editor1Secteur3......Before using this functionality, please ensure that a filter is associated with the storage resource (refer to section "Associate FDU with storage resource")Handling projects and geonotesYou can access projects or geonotes and use methods on these items :orion.{items}.{method(...)}# for projectsorion.projects.{method(...)}# for geonotesorion.geonotes.{method(...)}Here are the methods you can use to:search for items# get the result of the method search (as a list of items) and print itsearch=orion.{items}.search(q="",start=-1,num=100,all=False)# values in search are the default values# q is the query# start correspond to the number of the first result# num correspond to the number of results# define all as True to search both in Orion and Portal or False to search only in Portalprint(search)Forqparameter in case of geonotes# Search geonote for editor_aobq="owner:editor_aob AND type:Feature Collection AND tags:aob_geonote"# Search geonote for all usersq="type:Feature Collection AND tags:aob_geonote"# Search project for editor_aobq="owner:editor_aob AND type:Document Link AND tags:aob_project"# Search project for all usersq="type:Document Link AND tags:aob_project"get the DATA of an item from an item id, also called 'itemId'# get the result of the method data (json) and print itdata=orion.{items}.data('itemId')#you can get the data and export it in a new or existing json file using this method:data=orion.{items}.data_export('itemId','path_of_the_exported_file.json')#the path of the file must contain '.json' at the end#you can also use the id of the first item returned in the previous method :data=orion.{items}.data(search[0].get_id())print(data)add an item in aOB# return the result of the query, here in add_itemadd_item=orion.{items}.add_item("owner","title",text,snippet=None)# owner is the user that create the item# title is the title of the item you want to add# text is the json data to add# text can be for example 'text = orion.{items}.data('itemId')'# snippet is the description, set by default on None.#you can also import data from an existing json fileadd_item=orion.{items}.add_item_from_file("owner","title",'path_of_json_file.json',snippet=None)#you can print the return of the method, which is the result of the query send to the serverprint(add_item)update an item in aOB# return the result of the query, here in add_itemupdate_item=orion.{items}.update_item("itemId","title",text,snippet=None)# itemId is the id of the item to update# title is the new title of the item you want to update# text is the json data to update# text can be for example 'text = orion.{items}.data('itemId')'# snippet is the description, set by default on None.#you can also update an item with an existing json fileupdate_item=orion.{items}.update_item_from_file("itemId","title","path_of_json_file.json",snippet=None)#you can print the return of the method, which is the result of the query send to the serverprint(update_item)reassign the owner of an item# return the result of the query, here in add_itemreassign_item=orion.{items}.reassign("itemId","targetUsername")# itemId is the id of the item to reassign# targetUsername is the new username#you can print the return of the method, which is the result of the query send to the serverprint(reassign_item)delete an item# return the result of the query, here in add_itemdelete=orion.{items}.delete("itemId")# itemId is the id of the item to reassign#you can print the return of the method, which is the result of the query send to the serverprint(delete)Working with the ArcGIS API for Python.In some cases, OrionPy can work with the ArcGIS API for Python.
It is first required to install the API following itsdocumentation.Then, you can access its methods creating the class :fromorionpy.oriongis.oriongisimportOrionGIS# NB : parameter are the same as the Orion classorion_gis=OrionGIS(username,password,url_machine,portal)Access a Esri API methodorion_gis.gis.[....]Handling sharing on a service.Adding the Esri's API into OrionPy allowed to add the posibility of handling a service sharing.doesn't only allow to call methods from the API.
It gives the opportunity to create methods mixing calls to OrionPy and to the Esri API.service_url=""service=orion_gis.services.get(service_url)group_name=""group=orion_gis.groups.get(group_name)# Share a service with a grouporion_gis.services_gis_mgr.share(service,group.get_id())# Unshare a service with a grouporion_gis.services_gis_mgr.unshare(service,group.get_id())# Check if a service is share with a group :iforion_gis.service_gis_mgr.is_shared_with(service,group.get_id()):print('Service shared with group')else:print('Service not shared with group')# Get ID's of the groups with which a given service is sharedorion_gis.services_gis_mgr.get_groups_id_shared(service)Go furtherAccess to the full code documentation of the API is possible by opening
the fileindex.htmlon your web browser in the folder :docs/build/html.This folder can be found in the project'shomepage).Gitlab deposit is athttps://gitlab.com/esrifrance-public/orionpy/orionpy