pixelbin-io / pixelbin-python-sdk

MIT License
1 stars 1 forks source link

Using sync method "urlUpload()" #5

Open olmax04 opened 1 year ago

olmax04 commented 1 year ago

Hello, I ran into a problem using the urlUpload() method. It calls the urlUploadSync() method, but this creates a problem to run in a thread. How can I get around this? Here is an example of my code:

import os
import threading
from pixelbin import PixelbinConfig, PixelbinClient

def func():
    config = PixelbinConfig({
        'domain': "https://api.pixelbin.io",
        'apiSecret': f'{os.environ.get("PIXELBIN_TOKEN")}'
    })
    pixelbin: PixelbinClient = PixelbinClient(config=config)
    image_url = "<image_url>"
    image_name = image_url.split("/")[-1]
    task = pixelbin.assets.urlUpload(url=image_url, path="/", name=image_name)
    print(task)

if __name__ == "__main__":
    t = threading.Thread(target=func())
    t.start()

And i have problem:

Exception in thread Thread-1 (func):
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/Olmax04/Desktop/CRM-OBJECT-PARSER/grand-real-estate-test/test.py", line 16, in func
    task = pixelbin.assets.urlUpload(url=image_url, path="/", name=image_name)
  File "/Users/Olmax04/Desktop/CRM-OBJECT-PARSER/grand-real-estate/venv/lib/python3.10/site-packages/pixelbin/platform/PixelbinClient.py", line 277, in urlUpload
    return asyncio.get_event_loop().run_until_complete(
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/events.py", line 656, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1 (func)'.
olmax04 commented 1 year ago

How can i fix it?

pixelbin-dev commented 1 year ago

For running this with threads, you will have to maintain an event loop per thread.

canstralian commented 1 year ago

The issue you're experiencing is likely because you're calling the func() method immediately when creating the Thread object instead of passing the function itself.

To fix this, you need to pass the function object as the target parameter instead of calling it. Replace the line:

t = threading.Thread(target=func())

With:

t = threading.Thread(target=func)

Also, make sure to import the necessary modules for the PixelbinConfig and PixelbinClient classes:

import os
import threading
from pixelbin import PixelbinConfig, PixelbinClient

After making these changes, the func() method will be executed in a separate thread without any issues.

canstralian commented 1 year ago

And i have problem:

Exception in thread Thread-1 (func):
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/Olmax04/Desktop/CRM-OBJECT-PARSER/grand-real-estate-test/test.py", line 16, in func
    task = pixelbin.assets.urlUpload(url=image_url, path="/", name=image_name)
  File "/Users/Olmax04/Desktop/CRM-OBJECT-PARSER/grand-real-estate/venv/lib/python3.10/site-packages/pixelbin/platform/PixelbinClient.py", line 277, in urlUpload
    return asyncio.get_event_loop().run_until_complete(
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/events.py", line 656, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1 (func)'.

The error message indicates that there is no current event loop in the thread where the urlUpload method is being called.

To resolve this issue, you can create a new event loop in the func() method and use it to run the code that requires an event loop. Here's an updated version of your code with the necessary changes:

import os
import threading
import asyncio
from pixelbin import PixelbinConfig, PixelbinClient

def func():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    config = PixelbinConfig({
        'domain': "https://api.pixelbin.io",
        'apiSecret': f'{os.environ.get("PIXELBIN_TOKEN")}'
    })
    pixelbin: PixelbinClient = PixelbinClient(config=config)
    image_url = "<image_url>"
    image_name = image_url.split("/")[-1]
    task = loop.run_until_complete(
        pixelbin.assets.urlUpload(url=image_url, path="/", name=image_name)
    )
    print(task)

    loop.close()

if __name__ == "__main__":
    t = threading.Thread(target=func)
    t.start()

In this updated version, a new event loop is created using asyncio.new_event_loop(). Then, the newly created event loop is set as the current event loop using asyncio.set_event_loop(loop). Within the func() method, the code inside loop.run_until_complete() is executed using the newly created event loop.

Finally, the event loop is closed using loop.close().

By using this approach, you should be able to bypass the "no current event loop" error in the thread.