python-pyodata icon indicating copy to clipboard operation
python-pyodata copied to clipboard

404 using entity name as path when url is provided

Open setop opened this issue 2 years ago • 1 comments

I have a OData provider that retuns entities in the form of (EntityID, Url).

import requests
from requests.auth import HTTPBasicAuth

SERVICE_URL = 'https://REDACTED/odata_service.svc/'

basic = HTTPBasicAuth('redacted', 'redacted')
my_session = requests.Session()
my_session.auth = basic
r = my_session.get(SERVICE_URL)
# >>> r
# <Response [200]>
r.json()
# {'@odata.context': 'https://REDACTED/odata_service.svc/$metadata', 'value': [{'name': 'MyOData', 'url': '7588c426-3357-46e8-8021-255e1fb9aab6'}]}

When I try with pyodata:

import pyodata
client = pyodata.Client(SERVICE_URL, my_session)
client.entity_sets.MyOData.get_entities().count().execute()

I get a 404 : pyodata.exceptions.HttpError: HTTP GET for Entity Set MyOData failed with status code 404

It seems pyodata is trying to use the entity name property as a path (client.entity_sets.MyOData.get_entities().get_path() # => 'MyOData') instead of the url property.

When I do it manually with requests :

r = my_session.get(SERVICE_URL+'7588c426-3357-46e8-8021-255e1fb9aab6')
#>>> r
#<Response [200]>
len(r.json()['value'])
# 203

is works.

What do I missed ?

setop avatar Apr 04 '23 13:04 setop

Hi @setop this is hard to reproduce locally with information provided. But if the my_session.get(SERVICE_URL) returns directly some JSON payload with values of what you describe as entities (where I would expect return of Service Document, e.g. list of EntitySets - https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-odata/908358ab-f3b2-4c0a-a661-23f4e13a1778), then there is something strange in the odata service. Is it truly Odata or just REST?

I am not seeing in all your code examples (be it odata or direct requests) anything covering "Resource Path" part of odata URL, see https://www.odata.org/documentation/odata-version-2-0/uri-conventions/ for details. Just the service root itself. But this URL part will be generated by the client.entity_sets.MyOData.get_entities().count().execute() as this is exactly the Odata V2 standard.

my_session.get(SERVICE_URL+'7588c426-3357-46e8-8021-255e1fb9aab6') doesn't look as Odata URLs to me at all, just some REST GET.

Could you please provide $metadata document of the service - 'https://REDACTED/odata_service.svc/$metadata' ? You can redact all URLs there, but just the structure of entities, entitysets, entitytypes.

phanak-sap avatar Apr 19 '23 06:04 phanak-sap

no comment from author, closing as not actionable.

phanak-sap avatar Jul 10 '24 13:07 phanak-sap