Permission denied with os.setuid() in uvloop - python

I need to run a subprocess in my main process as "nobody" user, code like this:
# os.setuid(65534) # out the set_id work fine!!
logging.warning(f"outside user: {getpass.getuser()}")
# output: outside user: root
def set_id() -> None:
logging.warning(f"sub !sub! process user id is {os.getuid(), os.getgid(), os.getgroups()}!!!!!!!!!!!!")
# output: root:sub !sub! process user id is (0, 0, [])!!!!!!!!!!!!
assert os.getuid() == 0
logging.warning(f"inside user: {getpass.getuser()}")
# output: inside user: root
# os.setgid(65534) # work fine
os.setuid(65534) # can't work
pro = await asyncio.subprocess.create_subprocess_exec(
# *tmp_cmd,
"ls",
stdout=asyncio.subprocess.PIPE,
stdin=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd=self._cwd,
preexec_fn=set_id,
start_new_session=True,
close_fds=True,
)
When I call os.setuid(65534), raise an error PermissionError: [Errno 13] Permission denied.
But os.setgid(65534) work fine.
Extra info:
Inside the set_id function, os.getuid(), os.getgid(), os.getgroups() 's out is
(0, 0, [])
Outside the set_id, os.setuid(65534) work fine.
getpass.getuser() == "root"
That's why? How can I fix this? Thanks in advance.
Traceback:
ERROR:uvicorn.error:Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/uvicorn/protocols/websockets/websockets_impl.py", line 153, in run_asgi
result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
File "/usr/local/lib/python3.7/dist-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/fastapi/applications.py", line 149, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/applications.py", line 102, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/errors.py", line 146, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/middleware/cors.py", line 68, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/exceptions.py", line 58, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 550, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 283, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.7/dist-packages/starlette/routing.py", line 57, in app
await func(session)
File "/usr/local/lib/python3.7/dist-packages/fastapi/routing.py", line 209, in app
await dependant.call(**values)
File "/opt/MakerServer/app/api/routes/websockets_runner/runner.py", line 21, in wss_back
process = await WSProcess.create(file_m, ws=websocket)
File "/opt/MakerServer/app/services/processer.py", line 100, in create
self.proc: asyncio.subprocess.Process = await self._create_sub_process() # type: ignore
File "/opt/MakerServer/app/services/processer.py", line 136, in _create_sub_process
close_fds=True,
File "/usr/lib/python3.7/asyncio/subprocess.py", line 217, in create_subprocess_exec
stderr=stderr, **kwds)
File "uvloop/loop.pyx", line 2749, in subprocess_exec
File "uvloop/loop.pyx", line 2707, in __subprocess_run
File "uvloop/handles/process.pyx", line 596, in uvloop.loop.UVProcessTransport.new
File "uvloop/handles/process.pyx", line 98, in uvloop.loop.UVProcess._init
PermissionError: [Errno 13] Permission denied

The question does not provide all the elements, but here is what I would see:
os.setuid cannot generate an errno of 13. A permission error from setuid would be EPERM, which is errno 1.
therefore, I believe it's not the os.setuid that generates the exception.
my guess would be that the exception is generated after your set_id function returns, when Popen tries to open some file as user 65534 (it could be the target executable, some library or some config file that gets loaded down the line).
How to proceed to solve this:
confirm the issue by adding a try catch block around os.setuid. I'm 99% sure it won't trigger.
then try to run your command from the shell with su as nobody user. Most likely you'll get the same error.
You can also use strace -f on your program to see which system call fails and what parameters it is invoked with. That should point you in the right direction.

Related

Fastapi app: empty array or TypeError: Boolean value of this clause is not defined

So, Im doing simple todo-api app with fastapi and sqlmodel. Migrations went fine, but if I run my server, I dont see anything except empy array. I added some data in db file with DB Browser for SQLite, so it isn't empty.
And when I run my server and go to "/", I see only empty array and no data, and if I go to "/1/", I see this:
TypeError: Boolean value of this clause is not defined
My main.py:
from fastapi import FastAPI
import uvicorn
from endpoints.routers import router
from database.db import engine
from sqlmodel import SQLModel
app = FastAPI()
app.include_router(router)
# def create_db_and_tables():
# SQLModel.metadata.create_all(engine)
if __name__ == '__main__':
uvicorn.run("main:app", host='localhost', port=8000, reload=True)
# create_db_and_tables()
routers.py
from fastapi import APIRouter
from models.todo import ToDo
from repos.todo_repo import select_all_todos, select_todo
from database.db import session
from sqlmodel import Session, select
router = APIRouter()
#router.get("/", tags=['Todos'])
def show_todos():
todos = select_all_todos()
return todos
#router.get('/{id}/', response_model=ToDo, tags=['Todos'])
def select_one(id: int):
todo_found = select_todo(id)
return todo_found
repos:
from models.todo import ToDo
from sqlmodel import Session, select, or_
def select_all_todos():
with Session(engine) as session:
todos = select(ToDo)
results = session.exec(todos)
todo = results.all()
return todo
def select_todo(id):
with Session(engine) as session:
statement = select(ToDo)
statement = statement.where(ToDo.id==id)
if not statement:
return "Error"
result = session.exec(statement)
return result.first()
models:
from sqlmodel import Field, SQLModel
class ToDo(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str
is_done: bool = False
database.py file:
from sqlmodel import create_engine, Session
eng = 'database.db'
sqlite_url = f'sqlite:///{eng}'
engine = create_engine(sqlite_url, echo=True)
session = Session(bind=engine)
Traceback:
Traceback (most recent call last):
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
raise exc
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
await self.app(scope, receive, sender)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/routing.py", line 680, in __call__
await route.handle(scope, receive, send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/routing.py", line 275, in handle
await self.app(scope, receive, send)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/fastapi/routing.py", line 231, in app
raw_response = await run_endpoint_function(
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/fastapi/routing.py", line 162, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/anyio/to_thread.py", line 31, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
return await future
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 867, in run
result = context.run(func, *args)
File "/home/aleksandr/Programming/Sites/myTodo/backend/endpoints/routers.py", line 17, in select_one
todo_found = select_todo(id)
File "/home/aleksandr/Programming/Sites/myTodo/backend/repos/todo_repo.py", line 16, in select_todo
if not statement:
File "/home/aleksandr/Programming/Sites/myTodo/backend/venv/lib/python3.10/site-packages/sqlalchemy/sql/elements.py", line 590, in __bool__
raise TypeError("Boolean value of this clause is not defined")
TypeError: Boolean value of this clause is not defined
So, the exception is that you're not actually executing the statement in select_todo before checking for error. In SqlModel statement is a special kind of object to build and process a query, so it can't be directly checked for boolean value.
If you want to check if there are any results, place this statement under exec and check results instead.
There's no sense to check the statement itself in if, it's constructed successfully if no exception raised by that point
From reading the Traceback, I'd say that whatever type statement.where(ToDo.id==id) returns, seems not to have a __bool__() Magic Method defined. So you can't check for "truthy-ness" in the if statement.

Cant send message in aiogram

I have an id from a group chat, but when I try to send a message there, I get this error:
Traceback (most recent call last):
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\dispatcher\dispatcher.py", line 415, in _process_polling_updates
for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\dispatcher\dispatcher.py", line 235, in process_updates
return await asyncio.gather(*tasks)
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\dispatcher\handler.py", line 116, in notify
response = await handler_obj.handler(*args, **partial_data)
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\dispatcher\dispatcher.py", line 256, in process_update
return await self.message_handlers.notify(update.message)
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\dispatcher\handler.py", line 116, in notify
response = await handler_obj.handler(*args, **partial_data)
File "D:\github\repositories\python-bot\bot5.py", line 77, in cmd_create_dem
await bot.send_poll(chat_id=id,
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\bot\bot.py", line 1532, in send_poll
result = await self.request(api.Methods.SEND_POLL, payload)
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\bot\base.py", line 231, in request
return await api.make_request(await self.get_session(), self.server, self.__token, method, data, files,
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\bot\api.py", line 140, in make_request
return check_result(method, response.content_type, response.status, await response.text())
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\bot\api.py", line 115, in check_result
exceptions.BadRequest.detect(description)
File "D:\github\repositories\python-bot\venv\lib\site-packages\aiogram\utils\exceptions.py", line 140, in detect
raise err(cls.text or description)
aiogram.utils.exceptions.ChatNotFound: Chat not found
If I try to send to any other group, then everything works. Why is that?
code:
#dp.message_handler(commands=['opros'])
async def prikol(message: types.Message):
id = {-numbers}
await bot.send_message(id, 'ok')
i changed my id to {numbers}
My id has 14 characters including the minus, while the rest of the groups have like 10 characters. Could this affect something?
If you get id without -100 (example: 1234561) you need add "-100" to this id to use it with bot (ex: -1001234561)
I have two suggestions:
Be sure that your bot must be an admin of this group to be able to send messages.
Double check group id.

How to use FastAPI Depends objetcs with asyncio?

I have a FastAPI endpoint where it need to download some files from HDFS to the local server.
I'm trying to use asyncio to run the function that will download the files in a separate process.
I'm using FastAPI Depends to create a HDFS client and inject the object in the endpoint execution.
from fastapi import Depends, FastAPI, Request, Response, status
from hdfs import InsecureClient
import asyncio
from concurrent.futures.process import ProcessPoolExecutor
app = FastAPI()
HDFS_URLS = ['http://hdfs-srv.local:50070']
async def run_in_process(fn, *args):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(app.state.executor, fn, *args) # wait and return result
def connectHDFS():
client = InsecureClient(url)
yield client
def fr(id, img, client):
# my code here
client.download(id_identifica_foto_dir_hdfs, id_identifica_foto_dir_local, True, n_threads=2)
# my code here
return jsonReturn
#app.post("/")
async def main(request: Request, hdfsclient: InsecureClient = Depends(connectHDFS)):
# Decode the received message
data = await request.json()
message = base64.b64decode(data['data']).decode('utf-8').replace("'", '"')
message = json.loads(message)
res = await run_in_process(fr, message['id'], message['img'], hdfsclient)
return {
"message": res
}
#app.on_event("startup")
async def on_startup():
app.state.executor = ProcessPoolExecutor()
#app.on_event("shutdown")
async def on_shutdown():
app.state.executor.shutdown()
But I'm not able to pass ahead the hdfsclient object:
res = await run_in_process(fr, message['id'], message['img'], hdfsclient)
I'm getting the following error:
Traceback (most recent call last):
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/fastapi/routing.py", line 202, in app
dependant=dependant, values=values, is_coroutine=is_coroutine
File "/home/kleyson/.virtualenvs/reconhecimentofacial/lib/python3.7/site-packages/fastapi/routing.py", line 148, in run_endpoint_function
return await dependant.call(**values)
File "./asgi.py", line 86, in main
res = await run_in_process(fr, message['id'], message['img'], hdfsclient)
File "./asgi.py", line 22, in run_in_process
return await loop.run_in_executor(app.state.executor, fn, *args) # wait and return result
File "/usr/lib/python3.7/multiprocessing/queues.py", line 236, in _feed
obj = _ForkingPickler.dumps(obj)
File "/usr/lib/python3.7/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
How can have the hdfsclient available inside the def fr() function without the need to create a new connection on every new request ? I mean, how to create the hdfsclient on the application startup and be able to use it inside the function ?
The entire point of asyncio is to do what you are trying to achieve in the same process.
The typical example is a web crawler, where you open multiple requests, within the same thread/process, and then wait for them to finish. This way, you will get data from multiple urls without having to wait each single request before starting the next one.
The same applies in your case: call your async function that downloads the file, do your stuff and then wait for the file download to complete (if it hasn't completed yet). Sharing data between processes is not trivial, and your function is not working because of that reason.
I suggest you to first understand what async is and how it works, before jumping into doing something that you don't understand.
Some tutorials on asyncio
https://www.datacamp.com/community/tutorials/asyncio-introduction
https://realpython.com/lessons/what-asyncio/
https://docs.python.org/3/library/asyncio.html

Why am I getting TypeError with discord.py?

I've been using discord.py for a comfortable 3-4 months. I have maybe 2-3 projects using it, too. When I wanted to make a discord bot for my server which I'm using for Community Service and promoting good Mental Health, I received a TypeError as the output to my code, which at this point just responded to !hello.
Then, assuming I did something wrong (which is like 98% of the time) I tried to run my old discord.py projects that were working literally 4 days ago and I received the same TypeError.
Here is my code:
import discord
TOKEN = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
client = discord.Client()
#client.event
async def on_message(message):
print(message.content)
if message.author == client.user:
return
if message.content.startswith('!hello'):
msg = 'Hello {0.author.mention}'.format(message)
await message.channel.send(msg)
#client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
client.run(TOKEN)
And this is the full error I received:
Traceback (most recent call last):
File "C:/Users/lenovo/PycharmProjects/untitled/WIIT Discord.py", line 24, in <module>
client.run(TOKEN)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\client.py", line 640, in run
return future.result()
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\client.py", line 621, in runner
await self.start(*args, **kwargs)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\client.py", line 585, in start
await self.connect(reconnect=reconnect)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\client.py", line 499, in connect
await self._connect()
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\client.py", line 463, in _connect
await self.ws.poll_event()
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\gateway.py", line 471, in poll_event
await self.received_message(msg)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\gateway.py", line 425, in received_message
func(data)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\state.py", line 750, in parse_guild_create
guild = self._get_create_guild(data)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\state.py", line 725, in _get_create_guild
guild._from_data(data)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\guild.py", line 297, in _from_data
self._sync(guild)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\guild.py", line 324, in _sync
self._add_channel(TextChannel(guild=self, data=c, state=self._state))
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\channel.py", line 107, in __init__
self._update(guild, data)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\channel.py", line 131, in _update
self._fill_overwrites(data)
File "C:\Users\lenovo\PycharmProjects\untitled\venv\lib\site-packages\discord\abc.py", line 294, in _fill_overwrites
self._overwrites.append(_Overwrites(id=overridden_id, **overridden))
TypeError: __new__() got an unexpected keyword argument 'deny_new'
Process finished with exit code 1
I'm by absolutely no means an expert at Python or discord.py, but from what I can tell, either I have entered some wrong value, or there is a problem with the discord.py package. It's more likely that the former happened than the latter, so any help will be appreciated. Thanks!
Updating to the latest version of discord.py should fix it:
python3 -m pip install -U discord.py
Try updating your discord.py or maybe changing or reinstalling your IDE. I recently faced this problem with atom and it was fixed after I reinstalled atom. Make sure to save your projects in a textfile or something.

fastapi could not find model defintion when run with uvicorn

I want to host a pytorch model in a fastapi backend. When I run the code with python it is working fine. the depickled model can use the defined class. When the same file is started with uvicorn it cannot find the class definition.
Sourcecode looks like this:
import uvicorn
import json
from typing import List
from fastapi import Body, FastAPI
from fastapi.encoders import jsonable_encoder
import requests
from pydantic import BaseModel
#from model_ii import Model_II_b
import dill as pickle
import torch as T
import sys
app = FastAPI()
current_model = 'model_v2b_c2_small_ep15.pkl'
verbose_model = False # for model v2
class Model_II_b(T.nn.Module):
[...]
#app.post('/function')
def API_call(req_json: dict = Body(...)):
try:
# load model...
model = pickle.load(open('models/' + current_model, 'rb'))
result = model.dosomething_with(req_json)
return result
except Exception as e:
raise e
return {"error" : str(e)}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
When I run this with python main.py it is working fine and I am gettings results. When I run it with uvicorn main:app and send a request I get the following error:
AttributeError: Can't get attribute 'Model_II_b' on <module '__mp_main__' from '/opt/webapp/env/bin/uvicorn'>
both should be using the same python env as I use the uvicorn from within the env.
I hope someone has an idea what is wrong with my setup or code.
Update Stacktrace:
(model_2) root#machinelearning-01:/opt/apps# uvicorn main:app --env-file /opt/apps/env/pyvenv.cfg --reload
INFO: Loading environment from '/opt/apps/env/pyvenv.cfg'
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [164777] using statreload
INFO: Started server process [164779]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 127.0.0.1:33872 - "POST /ml/v2/predict HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/opt/apps/env/lib/python3.6/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/opt/apps/env/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/opt/apps/env/lib/python3.6/site-packages/fastapi/applications.py", line 183, in __call__
await super().__call__(scope, receive, send) # pragma: no cover
File "/opt/apps/env/lib/python3.6/site-packages/starlette/applications.py", line 102, in __call__
await self.middleware_stack(scope, receive, send)
File "/opt/apps/env/lib/python3.6/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/opt/apps/env/lib/python3.6/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/opt/apps/env/lib/python3.6/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/opt/apps/env/lib/python3.6/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py", line 550, in __call__
await route.handle(scope, receive, send)
File "/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/opt/apps/env/lib/python3.6/site-packages/fastapi/routing.py", line 197, in app
dependant=dependant, values=values, is_coroutine=is_coroutine
File "/opt/apps/env/lib/python3.6/site-packages/fastapi/routing.py", line 149, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/opt/apps/env/lib/python3.6/site-packages/starlette/concurrency.py", line 34, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
result = self.fn(*self.args, **self.kwargs)
File "./main.py", line 155, in API_call
raise e
File "./main.py", line 129, in API_call
model = pickle.load(open('models/' + current_model, 'rb'))
File "/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py", line 270, in load
return Unpickler(file, ignore=ignore, **kwds).load()
File "/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py", line 473, in load
obj = StockUnpickler.load(self)
File "/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py", line 463, in find_class
return StockUnpickler.find_class(self, module, name)
AttributeError: Can't get attribute 'Model_II_b' on <module '__mp_main__' from '/opt/apps/env/bin/uvicorn'>
enter code here
With the help from #lsabi I found the solution here https://stackoverflow.com/a/51397373/13947506
With the custom unpickler my problem was solved:
class CustomUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if name == 'Model_II_b':
from model_ii_b import Model_II_b
return Model_II_b
return super().find_class(module, name)
current_model = 'model_v2b_c2_small_ep24.pkl'
model = CustomUnpickler(open('models/' + current_model, 'rb')).load()

Categories