rbw / aiosnow

Asynchronous ServiceNow Library
MIT License
74 stars 12 forks source link

app.resource.get() raises AttributeError: 'tuple' object has no attribute 'read' #37

Closed sulbig closed 4 years ago

sulbig commented 4 years ago

When I do incidents = await r.get(selection), were 'r' is an app.resource, I get the exception:

Traceback (most recent call last):
  File "/...project-path.../hello.py", line 72, in <module>
    asyncio.run(main())
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/...project-path.../hello.py", line 59, in main
    incidents = await unresolved(app)
  File "/...project-path.../hello.py", line 43, in unresolved
    incidents = await r.get(selection, limit=50)
  File "/...project-path.../venv/lib/python3.8/site-packages/snow/resource/__init__.py", line 170, in get
    return await self.reader.collect(
  File "/...project-path.../venv/lib/python3.8/site-packages/snow/request/helpers/read.py", line 22, in collect
    content = await response.read()
AttributeError: 'tuple' object has no attribute 'read'

I am able to resolve it by modifying the return value(s) of the collection() function in the Reader() class in the read.py module to have both a response and content, as the read() function is being attempted against a tuple and not the response. I'm essentially skipping the read() since content is already there from the GetRequest() response tuple passed on from the _send() response.

class Reader:
    def __init__(self, resource):
        self.resource = resource
        self.schema = resource.schema_cls()

    async def stream(self, selection, **kwargs) -> Iterable:
        stream = StreamLike(self.resource, query=selection, **kwargs)
        while not stream.exhausted:
            async for content in stream.read():
                for item in self.schema.load(content, many=True):
                    yield item

    async def collect(self, selection, **kwargs) -> dict:
        response, content = await GetRequest(self.resource, query=selection, **kwargs).send()
        # content = await response.read()
        return self.schema.load(content, many=True)
rbw commented 4 years ago

Regression from when refactoring the request handling. It should be fixed with #39.

rbw commented 4 years ago

Fixed in 0.2.1