question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Uplink crashes on python3.9 when trying to serialize pydantic model

See original GitHub issue

Describe the bug Uplink crashes on python3.9 when trying to serialize model

To Reproduce This is the uplink class and method:

@tpa_error
@uplink_retry
class TPAService(FlapiBase):
    @uplink.returns.json(key=('data', 'appInstances', 'items'))
    @uplink.json
    @uplink.post('app-governance-graphql/graphql')
    def get_app_instance(self, **body: uplink.Body) -> List[AppInstance]:
        """Send a query Query to Third Party App's GraphQL API"""

This is the crash:

Traceback (most recent call last):
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/tests/casb/sit/test_sit.py", line 98, in test_sit_spark_invalid_log_file
tenant_app = verify_tenant_app_exists_in_tpa(app_name=APP_FOR_SIT_SPARK, tenant_id=tenant_id)
File "</home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/decorator.py:decorator-gen-64>", line 2, in _
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/shield/utils/retrier.py", line 38, in retry_decorator
return retry_call(f, fargs, fkwargs, exceptions, tries, delay, max_delay, backoff, jitter, log)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/retry/api.py", line 101, in retry_call
return __retry_internal(partial(f, *args, **kwargs), exceptions, tries, delay, max_delay, backoff, jitter, logger)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/retry/api.py", line 33, in __retry_internal
return f()
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/tests/fixtures/tpa.py", line 140, in _
tenant_app_instance = tpa_service().get_tenant_app_instance(query=query, variables=variables)[0]
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/builder.py", line 95, in __call__
self._request_definition.define_request(request_builder, args, kwargs)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/commands.py", line 287, in define_request
self._method_handler.handle_builder(request_builder)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/decorators.py", line 62, in handle_builder
annotation.modify_request(request_builder)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/returns.py", line 64, in modify_request
converter = request_builder.get_converter(
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/helpers.py", line 96, in get_converter
return self._converter_registry[converter_key](*args, **kwargs)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/converters/__init__.py", line 54, in __call__
converter = self._converter_factory(*args, **kwargs)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/converters/__init__.py", line 114, in chain
converter = func(factory)(*args, **kwargs)
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/models.py", line 42, in __call__
if self._is_relevant(type_, *args, **kwargs):
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/models.py", line 34, in _is_relevant
return utils.is_subclass(
File "/home/jenkins/workspace/execute_shield_pull_request_sit_test_us1/.tox/py39/lib/python3.9/site-packages/uplink/utils.py", line 81, in is_subclass
return inspect.isclass(cls) and issubclass(cls, class_info)
File "/usr/lib/python3.9/abc.py", line 123, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class

Expected behavior Not to crash

Additional context This results from an apparant change in issubclass() in python 3.9. I debugged this in 3.6 (where it’s working):

>>> cls
PyDev console: starting.
typing.List[shield.models.tpa.AppInstance]
>>> inspect.isclass(cls)
True
>>> issubclass(cls, class_info)
False

And 3.9:

>>> cls
PyDev console: starting.
typing.List[shield.models.tpa.AppInstance]
>>> inspect.isclass(cls)
True
>>> issubclass(cls, class_info)
Traceback (most recent call last):
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydevd_bundle/pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/abc.py", line 123, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class

Apparently issubclass() does not consider this to be a class in python 3.9, haven’t dug deep in its changelog to try and figure out why

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
liiightcommented, Jan 19, 2022

@prkumar this seems to be a little more complicated than I initially investigated, as a self contained example seems to work just fine:

import uplink
from pydantic import BaseModel


class HTTPBinData(BaseModel):
    foo: dict


class HTTPBinClient(uplink.Consumer):

    @uplink.returns.json(key=('json', 'data'))
    @uplink.json
    @uplink.post('/anything')
    def get_json(self, data: uplink.Field) -> list[HTTPBinData]:
        pass


c = HTTPBinClient(base_url='https://httpbin.org')
print(c.get_json(data=[{'foo': {}}]))

I believe this has something to do with pre-registered converters. I’ll continue to investigate

0reactions
bal-stancommented, Nov 16, 2022

Is there any progress on this?

Using:

  • Uplink 0.9.7
  • Pydantic 1.10.2
  • Python 3.10.4

I have a similar problem:

import typing as t

import typing_extensions as te
from pydantic import BaseModel
from uplink import Consumer, get


class Model(BaseModel):
    title: str
    description: str


class Client(Consumer):
    @get("some/endpoint")
    def get_data(self: te.Self) -> t.List[Model]:
        """List data."""

Then:

>>> a = Client("http://localhost:5000")
>>> a.get_data()
Traceback (most recent call last):
  File "pydantic/main.py", line 522, in pydantic.main.BaseModel.parse_obj
ValueError: dictionary update sequence element #0 has length 3; 2 is required

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/builder.py", line 106, in __call__
    return execution.start(
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 97, in start
    return self._io.execute(self)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 122, in execute
    return self._io.execute(executable)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 122, in execute
    return self._io.execute(executable)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 122, in execute
    return self._io.execute(executable)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/blocking_strategy.py", line 31, in execute
    return executable.execute()
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 93, in execute
    return self.state.execute(self)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/state.py", line 36, in execute
    return execution.before_request(self._request)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 56, in before_request
    return self.execute()
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 93, in execute
    return self.state.execute(self)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/state.py", line 105, in execute
    return execution.send(
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 73, in send
    return self._io.invoke(self._client.send, (request,), {}, callback)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 116, in invoke
    return self._io.invoke(func, args, kwargs, callback)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 116, in invoke
    return self._io.invoke(func, args, kwargs, callback)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 116, in invoke
    return self._io.invoke(func, args, kwargs, callback)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/blocking_strategy.py", line 21, in invoke
    return callback.on_success(response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/state.py", line 96, in on_success
    return self._context.execute()
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 93, in execute
    return self.state.execute(self)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/state.py", line 123, in execute
    return execution.after_response(self._request, self._response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 62, in after_response
    return self.execute()
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 93, in execute
    return self.state.execute(self)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/state.py", line 221, in execute
    return execution.finish(self._response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 79, in finish
    return self._io.finish(response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 125, in finish
    return self._io.finish(response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 125, in finish
    return self._io.finish(response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 143, in finish
    return self._invoke(
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 133, in _invoke
    return self._io.invoke(func, args, kwargs, FinishingCallback(self._io))
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/blocking_strategy.py", line 19, in invoke
    return callback.on_failure(type(error), error, tb)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/execution.py", line 108, in on_failure
    return self._io.fail(exc_type, exc_val, exc_tb)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/interfaces.py", line 300, in fail
    compat.reraise(exc_type, exc_val, exc_tb)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/six.py", line 719, in reraise
    raise value
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/io/blocking_strategy.py", line 16, in invoke
    response = func(*arg, **kwargs)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/clients/requests_.py", line 53, in apply_callback
    return callback(response)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/builder.py", line 47, in wrapper
    return func(self._consumer, *args, **kwargs)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/hooks.py", line 21, in wrapper
    return hook(*args, **kwargs)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/returns.py", line 39, in __call__
    return self._strategy(*args, **kwargs)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/converters/interfaces.py", line 6, in __call__
    return self.convert(*args, **kwargs)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/converters/typing_.py", line 33, in convert
    return [self._elem_converter(value)]
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/converters/interfaces.py", line 6, in __call__
    return self.convert(*args, **kwargs)
  File "/path/to/python/virtual/env/lib/python3.10/site-packages/uplink/converters/pydantic_.py", line 48, in convert
    return self._model.parse_obj(data)
  File "pydantic/main.py", line 525, in pydantic.main.BaseModel.parse_obj
pydantic.error_wrappers.ValidationError: 1 validation error for Model
__root__
  Model expected dict not list (type=type_error)

Looks like Uplink does not recognise the data being a list and passes it directly to pydantic, which crashes because it expects a dictionary as the root.

For clarity here is example data:

[
  {
    "title": "Title 1",
    "description": "Description 1"
    },
    {
    "title": "Title 2",
    "description": "Description 2"
    }
]
Read more comments on GitHub >

github_iconTop Results From Across the Web

Serialization — Uplink 0.9.7 documentation
A Declarative HTTP Client for Python, inspired by Retrofit. Table of Contents. Serialization. Using Marshmallow Schemas; Using Pydantic Models ...
Read more >
uplink 0.9.7 - PythonFix.com
The prkumar/uplink repo was created 4 years ago and was last updated Yesterday. ... Uplink crashes on python3.9 when trying to serialize pydantic...
Read more >
How to resolve pydantic model is not JSON serializable
Here the problem is that pydantic models are not json serializable by default, in your case, you can call data.dict() to serialize a...
Read more >
VMware Tanzu Greenplum 7 Beta Documentation
Uplink Assignment. 160. Using Four 100GbE Links. 161. Enabling VMware vSphere Distributed Switch (vDS). Health Check.
Read more >
Simple index - piwheels
... httpie-esni-auth byteark opencv-object-counter override-pydantic-settings mitopipeline s-exp-parser torchex transaction-test schematic-protection-model ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found