Open 4quen opened 6 years ago
Your issue lies in the following two lines, Service.entities
is a list
of odata.entity.Entity
and you specified your default fallback value to be a str
object.
default = 'Geids'
Order = Service.entities.get('Geids', default)
This is due to the fact the odata library wasn't able to read your XML response correctly (this was a recurring issue for me, I eventually ended up changing the XML namespaces under odata.metadata.MetaData.namespaces
for it to work) or your server doesn't have any Geids
entities, hope this helps
if 'Geids' not in Service.entities:
print('No geids entity definition found.')
exit()
Order = Service.entities['Geids']
Hi, Thank you for your help. The server definitely has some entities here.
Where exactly did you change the XML namespace? In the "metadata.py" ?
But I noticed that when trying the following lines:
for ent in Service.entities: print ('...') print (ent)
he doesn't give me anything back. (He even doesn't jump into the loop). Whis would happen that I have problems with the connection right? Is there something how I can test the connection?
Best regards, André
Some new comment from my side. I looked deeper in the original data and noticed that the odata service provides JSON files. The question now is: Does that have an influence and if yes, where do I have to change it?
Best regards, André
It looks like you're trying to use entities that aren't defined. The library requires reflect_entities or it will not populate the entities list. Try something like this:
Service = ODataService(url, auth=my_auth, reflect_entities=True)
A second problem that I had is with the location of the metadata (XML). In your example, the library would look for it here:
http://source.com/cdsodata/$metadata/
If that doesn't return the metadata XML, the library won't be able to build the entities. In my case, I had to use pull request #26 by nicenemo. It includes a fix to the metadata url to not have the trailing slash.
To answer your question: the library expects that the OData service uses JSON except for the metadata XML file.
Tim
Hi @tpow , sorry for the late answer, but I was on vacation.
I've added the reflect_entities but still no effect. The location of the metadata is the right one:
So that can't be the issue here.
Ok, but all entities are in json format, so that can't be neither the problem. Here are two examples of the entities (the first from https://source/cdsodata and the second from the Geids):
Your examples all have $metadata without a trailing slash. Does your OData site return the metadata if you add a slash after $metadata like /cdsodata/$metadata/? If not, you'll need pull request #26 by nicenemo.
Tim
Hi, yes it is also returning values when I add the slash ( https://source/cdsodata/$metadata/). So I think #26 will not help here?
Hi @4quen,
Perhaps enabling logging would give you some insight? Here's code similar to what I'm using to test things:
import logging
import odata
import requests
username = "XXX"
password = "YYY"
url = "https://source.com/cdsodata/"
with requests.Session() as s:
s.auth = (username, password)
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger("odata")
Service = odata.ODataService(url, session=s, reflect_entities=True)
print(Service)
print(len(Service.entities))
for ent in Service.entities:
print(ent)
If you're using basic auth, the above should work for you.
Also, in a web browser does both https://source.com/cdsodata/$metadata/ and https://source.com/cdsodata/$metadata give you the same results? (It should be providing XML)
Also, does the following give JSON results? https://source.com/cdsodata/Geids Based on your examples, it should.
Tim
Hi, I activated the log and received the following lines:
INFO: odata.metadata:Loading metadata document: http://source.com/cdsodata/$metadata/ DEBUG: urllib3.connectionpool:Starting new HTTP connection (1): source.com:80 DEBUG: urllib3.connectionpool:http://source.com:80 "GET /cdsodata/$metadata/ HTTP/1.1" 403 1233 INFO: odata.metadata: Loaded 0 entity sets, total 0 types <ODataService at http://source.com/cdsodata/> 0
And yes all of your three examples showed the expected results.
The 403 error indicates that the problem isn't with python-odata, but with your credentials, the access method, or the url. Perhaps you can't connect to that site using basic auth? If you need to authenticate before loading the $metadata url with a browser then you'll need to mimic that before python-odata will work. You might try connecting using the Requests module first and once you get that working I suspect python-odata will work fine.
In my previous example, I'd try replacing the Service = odata.ODataService line and everything following it with something like this:
response = s.get(url + '$metadata/')
print(response)
response.raise_for_status()
print(response.text)
You can then make changes to your authentication process until the response prints <Response [200]> and you see the xml from the metadata. For example, you should double check the credentials and url. If you're filling out a form in your browser before you can access the odata provider, you might need to post to the form URL (s.post) and then call the ODataService.
Good luck! Tim
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:![error](https://user-images.githubusercontent.com/5485172/44343016-05d52980-a48d-11e8-8090-715b836e7fad.png)
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?