I have an endpoint which saves uploaded image to it:
#router.post("/v1/installation/{installation_uuid}/image")
#db.create_connection
async def upload_installation_image(installation_uuid: UUID, request: Request):
content_type = request.headers["content-type"]
async with db.transaction():
installation = await get_installation_by_uuid(installation_uuid)
if not installation:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Installation {installation} not found")
try:
content = await request.body()
image_uuid = await save_installation_image(installation.uuid, content, content_type)
except Exception as e:
log.debug(f"An error raised while uploading image: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Error while uploading image to db"
)
return {"image_uuid": image_uuid}
save_installation_image make simple insert into DB.
In my tests I send 3 request to this endpoint. and all works fine:
tests.py
# upload image 1
data1 = b"\x01\x02\x03\x61\x05\x61"
response = session.post(
f"/v1/installation/{installation_uuid}/image", data=data1, headers={"content-type": "image/png"}
)
# upload image 2
data2 = b"\x01\x02\x03\x61\x05\x62"
response = session.post(
f"/v1/installation/{installation_uuid}/image", data=data2, headers={"content-type": "image/png"}
)
# upload image 3
data3 = b"\x01\x02\x03\x61\x05\x63"
response = session.post(
f"/v1/installation/{installation_uuid}/image", data=data3, headers={"content-type": "image/png"}
)
But when FE start calling that request, each request after first one start failing with this error:
Traceback (most recent call last):
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 404, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/uvicorn/middleware/message_logger.py", line 86, in __call__
raise exc from None
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/uvicorn/middleware/message_logger.py", line 82, in __call__
await self.app(scope, inner_receive, inner_send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
raise exc
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
await self.app(scope, receive, sender)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/routing.py", line 680, in __call__
await route.handle(scope, receive, send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/routing.py", line 275, in handle
await self.app(scope, receive, send)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/fastapi/routing.py", line 231, in app
raw_response = await run_endpoint_function(
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/fastapi/routing.py", line 160, in run_endpoint_function
return await dependant.call(**values)
File "/opt/kelvatek/camlin-relink-broker/toolbox/asyncio_db.py", line 153, in wrapper
return await func(*args, **kwargs)
File "/opt/kelvatek/camlin-relink-broker/src/installation.py", line 347, in upload_installation_image
installation = await get_installation_by_uuid(installation_uuid)
File "/opt/kelvatek/camlin-relink-broker/src/installation.py", line 64, in get_installation_by_uuid
row = (await db.execute(query, installation_uuid=str(installation_uuid))).fetchone()
File "/opt/kelvatek/camlin-relink-broker/toolbox/asyncio_db.py", line 116, in execute
return await active_connection.execute(query, **params)
File "/opt/kelvatek/camlin-relink-broker/toolbox/asyncio_db.py", line 50, in execute
return await t.execute(query, **params)
File "/opt/kelvatek/camlin-relink-broker/toolbox/asyncio_db.py", line 30, in execute
return await self.async_connection.execute(text(query).bindparams(**params))
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/ext/asyncio/engine.py", line 453, in execute
result = await greenlet_spawn(
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py", line 115, in greenlet_spawn
result = context.switch(*args, **kwargs)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1705, in _execute_20
return meth(self, args_10style, kwargs_10style, execution_options)
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/sql/elements.py", line 333, in _execute_on_connection
return connection._execute_clauseelement(
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1572, in _execute_clauseelement
ret = self._execute_context(
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1798, in _execute_context
conn = self._revalidate_connection()
File "/opt/kelvatek/camlin-relink-broker/venv/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 650, in _revalidate_connection
raise exc.ResourceClosedError("This Connection is closed")
sqlalchemy.exc.ResourceClosedError: This Connection is closed
Also, when I change by data to data which send FE, it start failing for me as well. What may cause this error, and why if I send real images connection close after first request?
P.S. If I send just 1 image, it works fine, so problem in sending several requests.
UPDATES
This is how I manage connection to db:
#asynccontextmanager
async def connection(self):
active_connection = self.get_active_connection()
if active_connection:
yield active_connection
return
async with self.engine.connect() as conn:
try:
wrapper = ConnectionWrapper(conn)
token = self.active_connection.set(wrapper)
await self.set_connection_options()
if not self.collation_check_done:
await self.check_collation()
self.collation_check_done = True
yield wrapper
finally:
self.active_connection.reset(token)
def create_connection(self, func):
#wraps(func)
async def wrapper(*args, **kwargs):
async with self.connection():
return await func(*args, **kwargs)
return wrapper
This is my Wrappers classes:
class TransactionWrapper:
def __init__(self, async_connection, async_transaction):
self.async_connection = async_connection
self.async_transaction = async_transaction
self.after_commit_callbacks = []
def add_after_commit_callback(self, fn):
self.after_commit_callbacks.append(fn)
async def execute(self, query, **params):
return await self.async_connection.execute(text(query).bindparams(**params))
async def commit(self):
await self.async_transaction.commit()
while self.after_commit_callbacks:
fn = self.after_commit_callbacks.pop(0)
fn()
async def rollback(self):
await self.async_transaction.rollback()
class ConnectionWrapper:
def __init__(self, async_connection):
self.async_connection = async_connection
self.active_transaction = contextvars.ContextVar('active_transaction')
async def execute(self, query, **params):
t = self.get_active_transaction()
if t:
return await t.execute(query, **params)
# create temporary transaction in case it doesn't exists (simulates autocommit feature)
async with self.transaction() as t:
return await t.execute(query, **params)
def get_active_transaction(self):
try:
return self.active_transaction.get()
except LookupError:
return None
#asynccontextmanager
async def transaction(self):
# reuse existing transaction
active_transaction = self.get_active_transaction()
if active_transaction:
yield active_transaction
return
async with self.async_connection.begin() as async_transaction:
wrapper = TransactionWrapper(self.async_connection, async_transaction)
token = self.active_transaction.set(wrapper)
try:
yield wrapper
except Exception:
await wrapper.rollback()
raise
else:
await wrapper.commit()
finally:
self.active_transaction.reset(token)
Related
I have a FastAPI application that needs to provide GET route to get all Items from a Postgres 13 database. The Item is defined and added from another app. The Item has a model like this:
class ItemDb(SQLModel, table=True):
__tablename__ = "items"
id: str = Field(
default_factory=uuid.uuid4, primary_key=True)
name: str
There is also table gadgets. Every Gadget has a foreign key which points to an Item:
class GadgetDb(SQLModel, table=True):
__tablename__ = "gadgets"
id: str = Field(
default_factory=uuid.uuid4, primary_key=True)
item_id: str = Field(..., foreign_key="items.id")
name: str
In my app, I want to retrieve just all the Items for now. I have created a simple model like this:
class Item(SQLModel):
id: str
key_name: str
This is my crud function:
class CRUDItem(CRUDBase[Item, None, None]):
def list(self, db: Session) -> List[Item]:
statement = select(self.model)
results = db.exec(statement)
return results.all()
item = CRUDItem(Item)
And this is my endpoint function:
from app.crud.crud_item import item
#router.get(
"/",
response_model=List[Item],
status_code=200,
response_model_exclude_unset=True,
)
def list_items(
session: Session = Depends(get_session),
) -> Any:
items = item.list(session)
return items
Now, this returns an error TypeError: 'SQLModelMetaclass' object is not iterable. Why this error occurs and how can I get all the rows from the database?
Edit. The error traceback:
INFO: 172.30.0.1:51432 - "GET /api/v1/items/ HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 404, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/usr/local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
raise exc
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/usr/local/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 680, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 275, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 231, in app
raw_response = await run_endpoint_function(
File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 162, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/usr/local/lib/python3.9/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "/usr/local/lib/python3.9/site-packages/anyio/to_thread.py", line 31, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "/usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
return await future
File "/usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 867, in run
result = context.run(func, *args)
File "/app/./app/api/api_v1/endpoints/items.py", line 29, in list_items
results = session.exec(select(Item)).all()
File "/usr/local/lib/python3.9/site-packages/sqlmodel/sql/expression.py", line 450, in select
return SelectOfScalar._create(*entities, **kw) # type: ignore
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 5309, in _create
return cls.create_legacy_select(*args, **kw)
File "<string>", line 2, in create_legacy_select
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 402, in warned
return fn(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 5165, in create_legacy_select
self._raw_columns = [
TypeError: 'ModelMetaclass' object is not iterable
Edit2. The class CRUDBase:
ModelType = TypeVar("ModelType", bound=Base)
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]): # 1
def __init__(self, model: Type[ModelType]): # 2
"""
CRUD object with default methods to Create, Read, Update, Delete (CRUD).
**Parameters**
* `model`: A SQLAlchemy model class
* `schema`: A Pydantic model (schema) class
"""
self.model = model
def get(self, db: Session, id: Any) -> Optional[ModelType]:
return db.query(self.model).filter(self.model.id == id).first() # 3
def list(
self, db: Session, *, skip: int = 0, limit: int = 100
) -> List[ModelType]:
return db.query(self.model).offset(skip).limit(limit).all() # 4
def create(self, db: Session, *, obj_in: CreateSchemaType) -> ModelType:
obj_in_data = jsonable_encoder(obj_in)
db_obj = self.model(**obj_in_data) # type: ignore
db.add(db_obj)
db.commit() # 5
db.refresh(db_obj)
return db_obj
The Item class isn't an ORM model (it doesn't have table=True), so you can't use it in database queries. Using ItemDb should resolve the issue.
I have the following code:
endpoints.py
from __future__ import annotations # this is important to have at the top
from fastapi import FastAPI
from pydantic import BaseModel
class MyOpt(BaseModel):
fieldfirst: str = "S"
fieldsecond: int = 1
fieldthird: str = None
fieldforth: list = []
fieldfifth: int
fieldsixth: list = [None, None]
fieldseventh: str = None
fieldeighth: Optional[int] = None
fieldnineth: Optional[str] = None
fieldtenth: Optional[list] = [None, None]
from typing import List, Optional
# Create object for fastAPI
app = FastAPI()
# START API ENDPOINTS
#app.get("/", tags=["root"])
def root():
return {"message": "REST API."}
# -- TESTING ENDPOINTS --
#app.get(
"/health",
name="health",
tags=["root"],
summary="Test connection to API",
status_code=200
)
def health():
return {"type": "complete"}
#app.post(
"/send_instruction",
name="send_instruction",
tags=["web"],
)
def send_instruction(myopts: MyOpt = None):
return {"result": "ok"}
run_api.py:
import uvicorn
if __name__ == "__main__":
uvicorn.run("endpoints:app", host="0.0.0.0", port=8822, reload=True, access_log=False)
When I call the api (python3 run_api.py), I get the following error only if I send any of the Optional values of MyOpt:
File "/home/ubuntu/.local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/applications.py", line 269, in __call__
await super().__call__(scope, receive, send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/exceptions.py", line 93, in __call__
raise exc
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/exceptions.py", line 82, in __call__
await self.app(scope, receive, sender)
File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/routing.py", line 670, in __call__
await route.handle(scope, receive, send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/routing.py", line 266, in handle
await self.app(scope, receive, send)
File "/home/ubuntu/.local/lib/python3.10/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/routing.py", line 217, in app
solved_result = await solve_dependencies(
File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 557, in solve_dependencies
) = await request_body_to_args( # body_params checked above
File "/home/ubuntu/.local/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 692, in request_body_to_args
v_, errors_ = field.validate(value, values, loc=loc)
File "pydantic/fields.py", line 857, in pydantic.fields.ModelField.validate
File "pydantic/fields.py", line 1074, in pydantic.fields.ModelField._validate_singleton
File "pydantic/fields.py", line 1121, in pydantic.fields.ModelField._apply_validators
File "pydantic/class_validators.py", line 313, in pydantic.class_validators._generic_validator_basic.lambda12
File "pydantic/main.py", line 686, in pydantic.main.BaseModel.validate
File "pydantic/main.py", line 339, in pydantic.main.BaseModel.__init__
File "pydantic/main.py", line 1038, in pydantic.main.validate_model
File "pydantic/fields.py", line 833, in pydantic.fields.ModelField.validate
pydantic.errors.ConfigError: field "fieldnineth" not yet prepared so type is still a ForwardRef, you might need to call SatOpt.update_forward_refs().
To send the request I use Postman and in Body as raw formated as JSON I have:
{"fieldfirst": "S", "fieldsecond": 1, "fieldthird": "a test", "fieldforth": [1,2], "fieldfifth": 42, "fieldsixth": [[1, 8, 3], [1, 9, 2]], "fieldseventh": "yey", "fieldnineth": "VV"}
What is wrong with my code?
from typing import List, Optional
Should be before the class definition
Im trying to get binane.com 5 minute kline data and send data to excel.
My code
#imports section
#link to excel
pairlistcount = 321
async def factorial(x,y):
client = await AsyncClient.create()
bm = BinanceSocketManager(client)
symbol = pairs.range('A'+str(x)).value
# start any sockets here
ts = bm.kline_socket(symbol, interval=KLINE_INTERVAL_5MINUTE)
# then start receiving messages
async with ts as tscm:
while True:
do something
await client.close_connection()
args = [(str(g+1), g+1) for g in range(pairlistcount)]
tasks = itertools.starmap(factorial, args)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
Sometimes it works perfectly, mostly it throws following error
most code deleted due to SO limit
return await self._request_api('get', path, signed, version, **kwargs)
File "C:\Users\ELCOT\AppData\Local\Programs\Python\Python39\lib\site-packages\binance\client.py", line 7174, in _request_api
return await self._request(method, uri, signed, **kwargs)
File "C:\Users\ELCOT\AppData\Local\Programs\Python\Python39\lib\site-packages\binance\client.py", line 7155, in _request
async with getattr(self.session, method)(uri, **kwargs) as response:
File "C:\Users\ELCOT\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\client.py", line 1138, in __aenter__
self._resp = await self._coro
File "C:\Users\ELCOT\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\client.py", line 559, in _request
await resp.start(conn)
File "C:\Users\ELCOT\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\client_reqrep.py", line 913, in start
self._continue = None
File "C:\Users\ELCOT\AppData\Local\Programs\Python\Python39\lib\site-packages\aiohttp\helpers.py", line 721, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
Please help with it.
Thanks in Advance.
I'm trying to add a field path of type PureWindowsPath to my model. After implementing a custom validator as suggested here https://github.com/samuelcolvin/pydantic/issues/2089#issuecomment-890018075 I get the following error when trying to access the SwaggerUI:
INFO: 127.0.0.1:7696 - "GET /api/openapi.json HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 371, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 59, in __call__
return await self.app(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 390, in handle
await self.app(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 241, in handle
await self.app(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 52, in app
response = await func(request)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 161, in openapi
return JSONResponse(self.openapi())
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 136, in openapi
self.openapi_schema = get_openapi(
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\openapi\utils.py", line 387, in get_openapi
definitions = get_model_definitions(
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\utils.py", line 24, in get_model_definitions
m_schema, m_definitions, m_nested_models = model_process_schema(
File "pydantic\schema.py", line 548, in pydantic.schema.model_process_schema
File "pydantic\schema.py", line 589, in pydantic.schema.model_type_schema
File "pydantic\schema.py", line 241, in pydantic.schema.field_schema
File "pydantic\schema.py", line 495, in pydantic.schema.field_type_schema
File "pydantic\schema.py", line 863, in pydantic.schema.field_singleton_schema
ValueError: Value not declarable with JSON Schema, field: name='path' type=PureWindowsPath required=True
My Pydantic config looks like this:
class CamelModel(BaseModel, ABC):
class Config:
alias_generator = camelize
allow_population_by_field_name = True
frozen = True
json_encoders = {
datetime: lambda dt: dt.isoformat(),
PureWindowsPath: str,
PurePath: str
}
use_enum_values = True
class Foo(CamelModel, ABC):
path: PureWindowsPath
extraction_version: str
class Foo2(Foo):
pass
You can use the following code to make this work. It creates a subclass with validators so you can customise the schema and validation how you want to:
here is a link to a relevant Github issue: https://github.com/tiangolo/sqlmodel/issues/235#issuecomment-1162063590
from psycopg2.extras import DateTimeTZRange as DateTimeTZRangeBase
from sqlalchemy.dialects.postgresql import TSTZRANGE
from sqlmodel import (
Column,
Field,
Identity,
SQLModel,
)
from pydantic.json import ENCODERS_BY_TYPE
ENCODERS_BY_TYPE |= {DateTimeTZRangeBase: str}
class DateTimeTZRange(DateTimeTZRangeBase):
#classmethod
def __get_validators__(cls):
yield cls.validate
#classmethod
def validate(cls, v):
if isinstance(v, str):
lower = v.split(", ")[0][1:].strip().strip()
upper = v.split(", ")[1][:-1].strip().strip()
bounds = v[:1] + v[-1:]
return DateTimeTZRange(lower, upper, bounds)
elif isinstance(v, DateTimeTZRangeBase):
return v
raise TypeError("Type must be string or DateTimeTZRange")
#classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(type="string", example="[2022,01,01, 2022,02,02)")
class EventBase(SQLModel):
__tablename__ = "event"
timestamp_range: DateTimeTZRange = Field(
sa_column=Column(
TSTZRANGE(),
nullable=False,
),
)
class Event(EventBase, table=True):
id: int | None = Field(
default=None,
sa_column_args=(Identity(always=True),),
primary_key=True,
nullable=False,
)
I'm trying to use await for json method,but it tell me error.
Traceback (most recent call last):
File "D:/project/shoes_crawler/shoes_crawler/spiders/tes.py", line 73, in <module>
loop.run_until_complete(main2())
File "C:\Miniconda3\envs\py35\lib\asyncio\base_events.py", line 467, in run_until_complete
return future.result()
File "C:\Miniconda3\envs\py35\lib\asyncio\futures.py", line 294, in result
raise self._exception
File "C:\Miniconda3\envs\py35\lib\asyncio\tasks.py", line 240, in _step
result = coro.send(None)
File "D:/project/shoes_crawler/shoes_crawler/spiders/tes.py", line 50, in main2
js = await r.json()
File "C:\Miniconda3\envs\py35\lib\site-packages\aiohttp\client_reqrep.py", line 1021, in json
await self.read()
File "C:\Miniconda3\envs\py35\lib\site-packages\aiohttp\client_reqrep.py", line 973, in read
self._body = await self.content.read()
File "C:\Miniconda3\envs\py35\lib\site-packages\aiohttp\streams.py", line 334, in read
raise self._exception
aiohttp.client_exceptions.ClientConnectionError: Connection closed
Here is code.
async def get_web():
async with aiohttp.ClientSession() as session:
async with session.get(url) as r:
# print(r)
return r
async def main2():
r = await get_web()
if r.status == 200:
print('200')
js = await r.json()
#do someting with js
await asyncio.sleep(1)
loop = asyncio.get_event_loop()
loop.run_until_complete(main2())
Besides,anybody know how to let main2() run forever?I want to check the target web if it update new thing