tuomur / python-odata Goto Github PK
View Code? Open in Web Editor NEWA simple library for read/write access to OData services
License: MIT License
A simple library for read/write access to OData services
License: MIT License
This is not a bug report.
I was wondering if there's some straightforward way to export schema entity types and their properties once the metadata has been retrieved from the given service (when constructing service with reflect_entities=True). Anyone found a way to do that using this library?
The ODATAV4 standard supports the string function "contains"
See 11.2.5.1.2 Built-in Query Functions in the following section
If implemented exactly the same way as this project already implements "startswith" and "endswith", then wildcard search on specified attributes can be used.
This was achieved by modifiying property.py
def contains(self, value):
value = self.escape_value(value)
return u'contains({0}, {1})'.format(self.name, value)
This may be out of scope, but I'm working with Redfish data from Dell, and reflect_entities
is not correctly loading the entities available.
From digging into this, it appears to be because DMTF/Redfish has broken their metadata up into many subfiles included by reference, and then entity containers just "extend" containers from these reference files.
Is it feasible to be able to load and cache these references when building the entities list? Or is something with a scope as large as this better off with an offline generation of service specific python classes?
Example data:
$metadata
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). All rights reserved.
-->
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="/redfish/v1/Schemas/ServiceRoot_v1.xml">
<edmx:Include Namespace="ServiceRoot" />
<edmx:Include Namespace="ServiceRoot.v1_0_0" />
<edmx:Include Namespace="ServiceRoot.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/AccountService_v1.xml">
<edmx:Include Namespace="AccountService" />
<edmx:Include Namespace="AccountService.v1_0_0" />
<edmx:Include Namespace="AccountService.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Chassis_v1.xml">
<edmx:Include Namespace="Chassis" />
<edmx:Include Namespace="Chassis.v1_0_0" />
<edmx:Include Namespace="Chassis.v1_0_1" />
<edmx:Include Namespace="Chassis.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ChassisCollection_v1.xml">
<edmx:Include Namespace="ChassisCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ComputerSystem_v1.xml">
<edmx:Include Namespace="ComputerSystem" />
<edmx:Include Namespace="ComputerSystem.v1_0_0" />
<edmx:Include Namespace="ComputerSystem.v1_0_1" />
<edmx:Include Namespace="ComputerSystem.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ComputerSystemCollection_v1.xml">
<edmx:Include Namespace="ComputerSystemCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/EthernetInterface_v1.xml">
<edmx:Include Namespace="EthernetInterface" />
<edmx:Include Namespace="EthernetInterface.v1_0_0" />
<edmx:Include Namespace="EthernetInterface.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/EthernetInterfaceCollection_v1.xml">
<edmx:Include Namespace="EthernetInterfaceCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Event_v1.xml">
<edmx:Include Namespace="Event" />
<edmx:Include Namespace="Event.v1_0_0" />
<edmx:Include Namespace="Event.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/EventService_v1.xml">
<edmx:Include Namespace="EventService" />
<edmx:Include Namespace="EventService.v1_0_0" />
<edmx:Include Namespace="EventService.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/IPAddresses_v1.xml">
<edmx:Include Namespace="IPAddresses" />
<edmx:Include Namespace="IPAddresses.v1_0_0" />
<edmx:Include Namespace="IPAddresses.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/JsonSchemaFile_v1.xml">
<edmx:Include Namespace="JsonSchemaFile" />
<edmx:Include Namespace="JsonSchemaFile.v1_0_0" />
<edmx:Include Namespace="JsonSchemaFile.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/JsonSchemaFileCollection_v1.xml">
<edmx:Include Namespace="JsonSchemaFileCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/EventDestination_v1.xml">
<edmx:Include Namespace="EventDestination" />
<edmx:Include Namespace="EventDestination.v1_0_0" />
<edmx:Include Namespace="EventDestination.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/EventDestinationCollection_v1.xml">
<edmx:Include Namespace="EventDestinationCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/LogEntry_v1.xml">
<edmx:Include Namespace="LogEntry" />
<edmx:Include Namespace="LogEntry.v1_0_0" />
<edmx:Include Namespace="LogEntry.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/LogEntryCollection_v1.xml">
<edmx:Include Namespace="LogEntryCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Role_v1.xml">
<edmx:Include Namespace="Role" />
<edmx:Include Namespace="Role.v1_0_0" />
<edmx:Include Namespace="Role.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/RoleCollection_v1.xml">
<edmx:Include Namespace="RoleCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/LogService_v1.xml">
<edmx:Include Namespace="LogService" />
<edmx:Include Namespace="LogService.v1_0_0" />
<edmx:Include Namespace="LogService.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/LogServiceCollection_v1.xml">
<edmx:Include Namespace="LogServiceCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Manager_v1.xml">
<edmx:Include Namespace="Manager" />
<edmx:Include Namespace="Manager.v1_0_0" />
<edmx:Include Namespace="Manager.v1_0_1" />
<edmx:Include Namespace="Manager.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ManagerCollection_v1.xml">
<edmx:Include Namespace="ManagerCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ManagerAccount_v1.xml">
<edmx:Include Namespace="ManagerAccount" />
<edmx:Include Namespace="ManagerAccount.v1_0_0" />
<edmx:Include Namespace="ManagerAccount.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ManagerAccountCollection_v1.xml">
<edmx:Include Namespace="ManagerAccountCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ManagerNetworkProtocol_v1.xml">
<edmx:Include Namespace="ManagerNetworkProtocol" />
<edmx:Include Namespace="ManagerNetworkProtocol.v1_0_0" />
<edmx:Include Namespace="ManagerNetworkProtocol.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Message_v1.xml">
<edmx:Include Namespace="Message" />
<edmx:Include Namespace="Message.v1_0_0" />
<edmx:Include Namespace="Message.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/MessageRegistry_v1.xml">
<edmx:Include Namespace="MessageRegistry" />
<edmx:Include Namespace="MessageRegistry.v1_0_0" />
<edmx:Include Namespace="MessageRegistry.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/MessageRegistryCollection_v1.xml">
<edmx:Include Namespace="MessageRegistryCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/MessageRegistryFile_v1.xml">
<edmx:Include Namespace="MessageRegistryFile" />
<edmx:Include Namespace="MessageRegistryFile.v1_0_0" />
<edmx:Include Namespace="MessageRegistryFile.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/MessageRegistryFileCollection_v1.xml">
<edmx:Include Namespace="MessageRegistryFileCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/PhysicalContext_v1.xml">
<edmx:Include Namespace="PhysicalContext" />
<edmx:Include Namespace="PhysicalContext.v1_0_0" />
<edmx:Include Namespace="PhysicalContext.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Power_v1.xml">
<edmx:Include Namespace="Power" />
<edmx:Include Namespace="Power.v1_0_0" />
<edmx:Include Namespace="Power.v1_0_1" />
<edmx:Include Namespace="Power.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Privileges_v1.xml">
<edmx:Include Namespace="Privileges" />
<edmx:Include Namespace="Privileges.v1_0_0" />
<edmx:Include Namespace="Privileges.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Redundancy_v1.xml">
<edmx:Include Namespace="Redundancy" />
<edmx:Include Namespace="Redundancy.v1_0_0" />
<edmx:Include Namespace="Redundancy.v1_0_1" />
<edmx:Include Namespace="Redundancy.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Processor_v1.xml">
<edmx:Include Namespace="Processor" />
<edmx:Include Namespace="Processor.v1_0_0" />
<edmx:Include Namespace="Processor.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ProcessorCollection_v1.xml">
<edmx:Include Namespace="ProcessorCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SerialInterface_v1.xml">
<edmx:Include Namespace="SerialInterface" />
<edmx:Include Namespace="SerialInterface.v1_0_0" />
<edmx:Include Namespace="SerialInterface.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SerialInterfaceCollection_v1.xml">
<edmx:Include Namespace="SerialInterfaceCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Session_v1.xml">
<edmx:Include Namespace="Session" />
<edmx:Include Namespace="Session.v1_0_0" />
<edmx:Include Namespace="Session.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SessionCollection_v1.xml">
<edmx:Include Namespace="SessionCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SessionService_v1.xml">
<edmx:Include Namespace="SessionService" />
<edmx:Include Namespace="SessionService.v1_0_0" />
<edmx:Include Namespace="SessionService.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SimpleStorage_v1.xml">
<edmx:Include Namespace="SimpleStorage" />
<edmx:Include Namespace="SimpleStorage.v1_0_0" />
<edmx:Include Namespace="SimpleStorage.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SimpleStorageCollection_v1.xml">
<edmx:Include Namespace="SimpleStorageCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Task_v1.xml">
<edmx:Include Namespace="Task" />
<edmx:Include Namespace="Task.v1_0_0" />
<edmx:Include Namespace="Task.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/TaskCollection_v1.xml">
<edmx:Include Namespace="TaskCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/TaskService_v1.xml">
<edmx:Include Namespace="TaskService" />
<edmx:Include Namespace="TaskService.v1_0_0" />
<edmx:Include Namespace="TaskService.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Thermal_v1.xml">
<edmx:Include Namespace="Thermal" />
<edmx:Include Namespace="Thermal.v1_0_0" />
<edmx:Include Namespace="Thermal.v1_0_1" />
<edmx:Include Namespace="Thermal.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/VirtualMedia_v1.xml">
<edmx:Include Namespace="VirtualMedia" />
<edmx:Include Namespace="VirtualMedia.v1_0_0" />
<edmx:Include Namespace="VirtualMedia.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/VirtualMediaCollection_v1.xml">
<edmx:Include Namespace="VirtualMediaCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/VLanNetworkInterface_v1.xml">
<edmx:Include Namespace="VLanNetworkInterface" />
<edmx:Include Namespace="VLanNetworkInterface.v1_0_0" />
<edmx:Include Namespace="VLanNetworkInterface.v1_0_1" />
<edmx:Include Namespace="VLanNetworkInterface.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/VLanNetworkInterfaceCollection_v1.xml">
<edmx:Include Namespace="VLanNetworkInterfaceCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/RedfishExtensions_v1.xml">
<edmx:Include Namespace="RedfishExtensions.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/OemManager_v1.xml">
<edmx:Include Namespace="EID_674_Manager" />
<edmx:Include Namespace="EID_674_Manager.v1_0_0" />
<edmx:Include Namespace="EID_674_Manager.v1_1_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/AttributeRegistry_v1.xml">
<edmx:Include Namespace="AttributeRegistry" />
<edmx:Include Namespace="AttributeRegistry.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Bios_v1.xml">
<edmx:Include Namespace="Bios" />
<edmx:Include Namespace="Bios.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Settings_v1.xml">
<edmx:Include Namespace="Settings" />
<edmx:Include Namespace="Settings.v1_0_0" />
<edmx:Include Namespace="Settings.v1_0_2" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SecureBoot_v1.xml">
<edmx:Include Namespace="SecureBoot" />
<edmx:Include Namespace="SecureBoot.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/DellBootSources_v1.xml">
<edmx:Include Namespace="DellBootSources" />
<edmx:Include Namespace="DellBootSources.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/DellBootSourcesRegistry_v1.xml">
<edmx:Include Namespace="DellBootSourcesRegistry" />
<edmx:Include Namespace="DellBootSourcesRegistry.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/DellComputerSystem_v1.xml">
<edmx:Include Namespace="DellComputerSystem" />
<edmx:Include Namespace="DellComputerSystem.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/DellJob_v1.xml">
<edmx:Include Namespace="DellJob" />
<edmx:Include Namespace="DellJob.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/DellJobCollection_v1.xml">
<edmx:Include Namespace="DellJobCollection" />
<edmx:Include Namespace="DellJobCollection.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/DellManager_v1.xml">
<edmx:Include Namespace="DellManager" />
<edmx:Include Namespace="DellManager.v1_0_0" />
</edmx:Reference>
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service">
<EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>
ServiceRoot_v1.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- -->
<!--
################################################################################
-->
<!-- # Redfish Schema: ServiceRoot v1.0.2 -->
<!-- # -->
<!--
# For a detailed change log, see the README file contained in the DSP8010 bundle,
-->
<!--
# available at http://www.dmtf.org/standards/redfish
-->
<!--
# Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF).
-->
<!--
# For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright
-->
<!--
################################################################################
-->
<!-- -->
<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
<edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/cs01/vocabularies/Org.OData.Core.V1.xml">
<edmx:Include Namespace="Org.OData.Core.V1" Alias="OData" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Resource_v1.xml">
<edmx:Include Namespace="Resource" />
<edmx:Include Namespace="Resource.v1_0_0" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/RedfishExtensions_v1.xml">
<edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish" />
<edmx:Include Namespace="Validation.v1_0_0" Alias="Validation" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/EventService_v1.xml">
<edmx:Include Namespace="EventService" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/AccountService_v1.xml">
<edmx:Include Namespace="AccountService" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ComputerSystemCollection_v1.xml">
<edmx:Include Namespace="ComputerSystemCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ChassisCollection_v1.xml">
<edmx:Include Namespace="ChassisCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/ManagerCollection_v1.xml">
<edmx:Include Namespace="ManagerCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/TaskService_v1.xml">
<edmx:Include Namespace="TaskService" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SessionService_v1.xml">
<edmx:Include Namespace="SessionService" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/Message_v1.xml">
<edmx:Include Namespace="Message" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/JsonSchemaFileCollection_v1.xml">
<edmx:Include Namespace="JsonSchemaFileCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/MessageRegistryFileCollection_v1.xml">
<edmx:Include Namespace="MessageRegistryFileCollection" />
</edmx:Reference>
<edmx:Reference Uri="/redfish/v1/Schemas/SessionCollection_v1.xml">
<edmx:Include Namespace="SessionCollection" />
</edmx:Reference>
<edmx:DataServices>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ServiceRoot">
<EntityType Name="ServiceRoot" BaseType="Resource.v1_0_0.Resource" Abstract="true">
<Annotation Term="OData.Description" String="This resource represents the root of the Redfish service, located at the \redfish\v1 URI. As a hypermedia API, all other resources accessible through the Redfish interface on this device are linked directly or indirectly from the Service Root." />
<Annotation Term="OData.LongDescription" String="This object represents the root Redfish service. All values for resources described by this schema shall comply to the requirements as described in the Redfish specification." />
</EntityType>
</Schema>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ServiceRoot.v1_0_0">
<EntityContainer Name="ServiceContainer">
<Singleton Name="Service" Type="ServiceRoot.ServiceRoot" />
<Singleton Name="Systems" Type="ComputerSystemCollection.ComputerSystemCollection" />
<Singleton Name="Chassis" Type="ChassisCollection.ChassisCollection" />
<Singleton Name="Managers" Type="ManagerCollection.ManagerCollection" />
<Singleton Name="Tasks" Type="TaskService.TaskService" />
<Singleton Name="AccountService" Type="AccountService.AccountService" />
<Singleton Name="SessionService" Type="SessionService.SessionService" />
<Singleton Name="EventService" Type="EventService.EventService" />
<Singleton Name="Registries" Type="MessageRegistryFileCollection.MessageRegistryFileCollection" />
<Singleton Name="JsonSchemas" Type="JsonSchemaFileCollection.JsonSchemaFileCollection" />
<Singleton Name="Sessions" Type="SessionCollection.SessionCollection" />
</EntityContainer>
<EntityType Name="ServiceRoot" BaseType="ServiceRoot.ServiceRoot">
<Annotation Term="OData.Description" String="This object represents the root Redfish service." />
<Annotation Term="OData.LongDescription" String="This object represents the root Redfish service. All values for resources described by this schema shall comply to the requirements as described in the Redfish specification." />
<Property Name="RedfishVersion" Type="Edm.String" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="The version of the Redfish service" />
<Annotation Term="OData.LongDescription" String="The value of this string shall represent the version of the Redfish service. The format of this string shall be of the format majorversion.minorversion.errata in compliance with Protocol Version section of the Redfish specification. " />
<Annotation Term="Validation.Pattern" String="^\\d+\\.\\d+\\.\\d+$" />
</Property>
<Property Name="UUID" Type="Resource.UUID">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="Unique identifier for a service instance. When SSDP is used, this value should be an exact match of the UUID value returned in a 200OK from an SSDP M-SEARCH request during discovery. " />
<Annotation Term="OData.LongDescription" String="The value of this string shall represent the id of the Redfish service instance. The format of this string shall be a 32-byte value in the form 8-4-4-4-12. If SSDP is used, this value shall be an exact match of the UUID value returned in a 200OK from an SSDP M-SEARCH request during discovery. RFC4122 describes methods that can be used to create a UUID value. The value should be considered to be opaque. Client software should only treat the overall value as a universally unique identifier and should not interpret any sub-fields within the UUID." />
</Property>
<NavigationProperty Name="Systems" Type="ComputerSystemCollection.ComputerSystemCollection" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to a collection of Systems." />
<Annotation Term="OData.LongDescription" String="This object shall only contain a reference to a collection of resources that comply to the Systems schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="Chassis" Type="ChassisCollection.ChassisCollection" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to a collection of Chassis." />
<Annotation Term="OData.LongDescription" String="This object shall only contain a reference to a collection of resources that comply to the Chassis schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="Managers" Type="ManagerCollection.ManagerCollection" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to a collection of Managers." />
<Annotation Term="OData.LongDescription" String="This object shall only contain a reference to a collection of resources that comply to the Managers schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="Tasks" Type="TaskService.TaskService" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to the Task Service." />
<Annotation Term="OData.LongDescription" String="The classes structure shall only contain a reference to a resource that complies to the TaskService schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="SessionService" Type="SessionService.SessionService" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to the Sessions Service." />
<Annotation Term="OData.LongDescription" String="The classes structure shall only contain a reference to a resource that complies to the SessionService schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="AccountService" Type="AccountService.AccountService" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to the Account Service." />
<Annotation Term="OData.LongDescription" String="The classes structure shall only contain a reference to a resource that complies to the AccountService schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="EventService" Type="EventService.EventService" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to the EventService." />
<Annotation Term="OData.LongDescription" String="The classes structure shall only contain a reference to a resource that complies to the EventService schema." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="Registries" Type="MessageRegistryFileCollection.MessageRegistryFileCollection" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to a collection of Registries." />
<Annotation Term="OData.LongDescription" String="This object shall contain a reference to Message Registry." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<NavigationProperty Name="JsonSchemas" Type="JsonSchemaFileCollection.JsonSchemaFileCollection" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="This is a link to a collection of Json-Schema files." />
<Annotation Term="OData.LongDescription" String="This object shall only contain a reference to a collection of resources that comply to the SchemaFile schema where the files are Json-Schema files." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
<Property Name="Links" Type="ServiceRoot.v1_0_0.Links" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="Contains references to other resources that are related to this resource." />
<Annotation Term="OData.LongDescription" String="The Links property, as described by the Redfish Specification, shall contain references to resources that are related to, but not contained by (subordinate to), this resource." />
<Annotation Term="Redfish.Required" />
</Property>
</EntityType>
<ComplexType Name="Links" BaseType="Resource.Links">
<NavigationProperty Name="Sessions" Type="SessionCollection.SessionCollection" Nullable="false">
<Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read" />
<Annotation Term="OData.Description" String="Link to a collection of Sessions" />
<Annotation Term="OData.LongDescription" String="This property shall contain the link to a collection of Sessions." />
<Annotation Term="OData.AutoExpandReferences" />
</NavigationProperty>
</ComplexType>
</Schema>
<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="ServiceRoot.v1_0_2">
<EntityType Name="ServiceRoot" BaseType="ServiceRoot.v1_0_0.ServiceRoot" />
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Pardon my Python, I am a Java programmer.
I changed your code in my fork to support custom http headers. As far as I understand your version does not support it.
Custom http headers: https://github.com/nicenemo/python-odata/commit/8037ed59f1aa5aad90503bc4a6ad2908dab4b661
I'm currently able to read and update items from an OData source using python-odata, however I'm struggling with the understanding of how to add new records to entities after using reflection to enumerate the service. Is there any documentation available that would assist in this process?
In metadata.py, get_entity_sets() will create EnumTypes for all name/value pairs of enumtype members.
If the name of the enumtype memer is a zero-length string, creating the enumtype will cause an exception as _is_sunder() in enum.py cannot check for name[0] as it doesn't exist.
I'm not quite sure where the best place would be to fix this. I'm currently using a workaround of converting the name of the enumtype to a single space character, but that's obviously not quite right.
I don't have any control over the OData interface I'm querying, and I'm at a loss of why someone would name a Enumtype member with a zero length string in the first place, but this is what I'm dealing with. Any suggestions welcome!
I came to this while trying to integrate it with Microsoft Dynamics 2016 and couldn't figure how to connect to it, because ODataService
had auth param it was easy to integrate Dynamics authentication with it, simply use HttpNtlmAuth
.
import requests
auth_username = ''
auth_password = ''
basic_url = ''
odata_url = ''
session = requests.Session()
session.auth = HttpNtlmAuth(auth_username, auth_password, session)
session.get(basic_url) # should return 200
service = ODataService(odata_url, reflect_entities=True, session=session)
We noticed that after HttpNtlmAuth
request, it was redirected to /adfs/ls
page to perform wsignin1
request. I don't know much about Dynamics nor Microsoft standers but I am happy to share the code if somebody needs it.
$ python
Python 3.8.10 (default, Nov 22 2023, 10:22:35)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from odata import ODataService
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/tom/development/venv/lib/python3.8/site-packages/odata/__init__.py", line 5, in <module>
from .service import ODataService
File "/home/tom/development/venv/lib/python3.8/site-packages/odata/service.py", line 63, in <module>
from .context import Context
File "/home/tom/development/venv/lib/python3.8/site-packages/odata/context.py", line 5, in <module>
from odata.query import Query
File "/home/tom/development/venv/lib/python3.8/site-packages/odata/query.py", line 70, in <module>
class Query(Generic[Q]):
File "/home/tom/development/venv/lib/python3.8/site-packages/odata/query.py", line 280, in Query
def all(self) -> list[Q]:
TypeError: 'type' object is not subscriptable
I'm possibly missing something, but it seems like a query using select should return entities just like the same query without the select. (Obviously not all properties will be populated, but that's kind of the point of a select). Here's the Demo example:
from odata import ODataService
url = 'http://services.odata.org/V4/Northwind/Northwind.svc/'
Service = ODataService(url, reflect_entities=True)
Supplier = Service.entities['Supplier']
query = Service.query(Supplier)
query = query.limit(2)
query = query.order_by(Supplier.CompanyName.asc())
for supplier in query:
print('Company:', supplier.CompanyName)
This works fine and prints the CompanyNames of the suppliers. However, if you add
query = query.select(Supplier.CompanyName)
Then you also need to change the print statement like this:
print('Company:', supplier['CompanyName'])
The syntax change is unexpected and switching from the object to JSON dict is strange. It'd be nice if the query would return the entities with only the selected properties populated so the code doesn't need to change. In fact, it looks like the entity already supports this using from_data.
I commented out part of the _create_model method in query.py and it seems to work fine --- the entity is returned when using the select and the other properties are left as None.
def _create_model(self, row):
#if len(self.options.get('$select', [])):
# return row
#else:
e = self.entity.__new__(self.entity, from_data=row)
es = e.__odata__
es.connection = self.connection
return e
Is there some reason this isn't the default behavior that I'm missing? The only thing I can think that might be useful is to keep track of when an entity is constructed like this so you cannot accidentally save it and lose data.
Current implementation assumes only one PK per entity.
Hi,
First off, I have to say, your code is absolutely gorgeous.
On to the bug -- I'm trying to reflect a schema where all entity types have base types that are entity types themselves. I am relatively new to OData so I really have no idea how common this is. I assumed most OData schemas use Edm.* types or something like that.
It looks like all_types is first pulling enum types and then adding entity typeclass to all_types, but I am running into a TypeError when the code tries to create a typeclass with a base_type that has not been reflected yet. (TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases)
entity_class = type(entity_name, (parent_entity_class,), object_dict) # type: EntityBase
line 89 in metadata.py
parent_entity_class should be pfs.ENTITY in my schema for a particular entity 'ACCESS_LEVEL', but pfs.ENTITY is not a typeclass in all_types yet, so in my run of this code it is None...hence the metaclass conflict. I think. Would this problem be resolved by first reflecting everything where entity_dict.get('name')? The choice of which entities to create first now does not seem explicit.
Hello.
I would like to address this issue as I cannot find any solution to it.
I call function raw, like this: Service.query(entity).raw("('ID')")
And it keeps creating request url like this: /odata/Products?('ID')
Using .get is not an option as .get uses filter on get-all which I dont have implemented!
According to the OData specification $metadata
urls should work without trailing '/'. They may also work with trailing slash.
OData services expose their entity
model according to OData-CSDL
at the metadata URL, formed by
appending $metadata
to the service root URL
Example 5: Metadata document URL
http://host/service/$metadata
OData services MAY expose their entity model
as a service, according to [OData-CSDL], by appending a trailing slash (/) to the metadata document URL.
Example 6: Metadata service root URL
http://host/service/$metadata/
Olingo Odata services for example do not have the trailing '/' in their $metadata url.
I forked your repo and fixed that. I did not fix the unit test yet. Do you want a pull request?
I tried to get the data from this site:
http://knesset.gov.il/Odata/ParliamentInfo.svc/
This is the code I used:
from odata import ODataService
url = 'http://knesset.gov.il/Odata/ParliamentInfo.svc/'
Service = ODataService(url, reflect_entities=True)
print(len(Service.entities))
The result is:
0
It should return a dictionary with all the tables on the site.
There is data on the site, and I think the format is good.
Maybe the problem is with the metadata.
Is there a way to fix this?
Thanks,
(basic) authentication seems to be an option to ODataService , but how should it be used?
pls add an example.
Currently NavigationProperty objects need to refer to an Entity class. Two classes referencing eachother does not work unless NavigationProperties are added after everything else. Should we support Entity refs as strings? How to get the Entity behind the string?
The ..egg directory is not ignored in .gitignore
Fix: https://github.com/nicenemo/python-odata/commit/fccb8b089b85312dc32d6224dbf85dcc97c02e3a
Is https supported?
it always returns an empty list {} when I use it with python-odata
(example url: https://services.odata.org/V4/Northwind/Northwind.svc/ )
Your version converts spaces in filter strings like myprop eq 'foo'
into myprop+eq+%27foo%27'
.
An Olingo based OData service expects %20
for a space.
Do you want a pull request for that?
Fix in my fork: https://github.com/nicenemo/python-odata/commit/7a5c115df7f8bdc33453c1d9876167edbe49be5d
Since perform-requests (such as _do_get()
) methods of ODataConnection
wrapped in catch_requests_errors
decorator, ODataConnectionError
raised without status_code.
Must add status_code assigning in catch_requests_errors
decorator.
I am getting a dictionary with no entities on executing
Service = ODataService(URL, auth=my_auth, reflect_entities = True)
Service.entities
What could be the possible reasons for this?
If I have a query like:
https://jacksonlabstest.platformforscience.com/DEV/odata/INDIRECT_CALORIMETRY_ASSAY_DATA$count=true&$expand=EXPERIMENT_SAMPLE($expand=ENTITY/pfs.MOUSE_SAMPLE_LOT($expand=MOUSESAMPLELOT_CBABATCH))
(ie nested expansions)
How do I specify these using this library? I've tried a dozen different things but can't seem to figure it out.
I really don't know if this is the right place to write my problem here. If not, pardon me!
I tried out the library but I ran into the following error:
I'm quite sure I did everything right (and I also doublechecked the providing oDataService if the values were set right). Also username and password are right.
This is my code:
`from odata import ODataService
from requests.auth import HTTPBasicAuth
import requests
url = 'http://source.com/cdsodata/'
my_auth = HTTPBasicAuth('XXX', 'YYY')
Service = ODataService(url, auth=my_auth)
default = 'Geids'
Order = Service.entities.get('Geids', default)
query = Service.query(Order)
query = query.limit(100)
for entity in query:
print(entity.Geid)`
Maybe you can help me?
Singletons provide a way to represent a single item at the service root. They live in the EntityContainer tag, just like EntitySets, Actions, and Functions. I would be willing to add support if you would be willing to merge my changes...
Navigation properties that go to a Collection are not reflected into model.
Has anyone else observed this?
In my metadata doc:
<EntityType Name="TestResultType">
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="id" Type="Edm.Int32" Nullable="false"/>
<Property Name="name" Type="Edm.String"/>
<Property Name="active" Type="Edm.Boolean" Nullable="false"/>
<Property Name="description" Type="Edm.String"/>
<Property Name="createdOn" Type="Edm.DateTimeOffset" Nullable="false"/>
<Property Name="createdBy" Type="Edm.Guid" Nullable="false"/>
<Property Name="lastUpdatedOn" Type="Edm.DateTimeOffset"/>
<Property Name="lastUpdatedBy" Type="Edm.Guid"/>
<NavigationProperty Name="createdByUser" Type="Entities.User"/>
<NavigationProperty Name="lastUpdatedByUser" Type="Entities.User"/>
<NavigationProperty Name="testResults" Type="Collection(Entities.TestResult)"/>
</EntityType>
could you tag the "stable" master branch with some tags? That we we can use pip to install
pip install --upgrade --no-cache-dir --ignore-installed https://github.com/pocin/python-odata/archive/v0.1.0.zip
Is there a way to set default values to properties?
Single quotes in search strings break everything.
Alias support added in #8 works only partially. Some implementations use both alias and full name when defining Entities and EntitySets. python-odata should be able to refer to the same object with both type names.
I thought this might be helpful for others (and to remind me to create a PR):
OData v4 has a trim string function. I believe this can be implemented in property.py like this:
def trim(self):
return u'trim({0})'.format(self.name)
Using this library to consume Microsoft Dynamics 365 Business Central (formerly Microsoft Dynamics NAV) ODataV4 web services, I had to find a way to not be limited to the default service company of the endpoint.
Normally, to specify a company within the source database to connect to, the url would be in the form of <endpoint>/Company('CompanyName')/EntitySet
But providing this as url
to the ODataService class does not accept $metadata
The solution is to pass <endpoint>/Company('CompanyName')/
as url
to ODataService and pass <endpoint>/
as new metadata_url
parameter to ODataService
And then additionaly, in the Metadata class, use the metadata_url
instead of url
Happy to contribute the code changes if required
LOVE this library
In metadata.py, _parse_enumtype() will go through all members of an enumtype_element and append the name/value pairs to enum['members']. It will convert all string values to int, which causes problems later-on in get_entity_sets() when EnumType is called.
Feel free to correct me on this, but in trying to parse a large OData interface I've come across this issue and it made me wonder why the conversion is taking place in the first case. I've removed the conversion in my local copy for now.
I'm not so much used with bare installations.
Hi,
I have tried to launch a request with a JSON format like the one we can find on this link; http://services.odata.org/V3/OData/OData.svc/Products?$format=json
which is from this website, just below Read an EntitySet:
https://blogs.msdn.microsoft.com/leohu/2013/10/04/odata-and-json-payload-examples/
I did:
url_test = "http://services.odata.org/V3/OData/OData.svc/Products?$format=json"
service = ODataService(url, reflect_entities=False)
service.entities['ID']
but it doesnt work
thanks for your help
What could be the cause of the error message when loading metadata?
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.