kandi background
Explore Kits

uvicorn | An ASGI web server, for Python 🦄 | Reactive Programming library

 by   encode Python Version: 0.17.6 License: BSD-3-Clause

 by   encode Python Version: 0.17.6 License: BSD-3-Clause

Download this library from

kandi X-RAY | uvicorn Summary

uvicorn is a Python library typically used in Programming Style, Reactive Programming applications. uvicorn has no bugs, it has no vulnerabilities, it has build file available, it has a Permissive License and it has high support. You can install using 'pip install uvicorn' or download it from GitHub, PyPI.
Requirements: Python 3.7+ (For Python 3.6 support, install version 0.16.0.). Uvicorn is an ASGI web server implementation for Python. Until recently Python has lacked a minimal low-level server/application interface for async frameworks. The ASGI specification fills this gap, and means we're now able to start building a common set of tooling usable across all async frameworks. Uvicorn supports HTTP/1.1 and WebSockets.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • uvicorn has a highly active ecosystem.
  • It has 5109 star(s) with 429 fork(s). There are 80 watchers for this library.
  • There were 9 major release(s) in the last 12 months.
  • There are 55 open issues and 518 have been closed. On average issues are closed in 151 days. There are 44 open pull requests and 0 closed requests.
  • It has a negative sentiment in the developer community.
  • The latest version of uvicorn is 0.17.6
uvicorn Support
Best in #Reactive Programming
Average in #Reactive Programming
uvicorn Support
Best in #Reactive Programming
Average in #Reactive Programming

quality kandi Quality

  • uvicorn has 0 bugs and 0 code smells.
uvicorn Quality
Best in #Reactive Programming
Average in #Reactive Programming
uvicorn Quality
Best in #Reactive Programming
Average in #Reactive Programming

securitySecurity

  • uvicorn has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • uvicorn code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
uvicorn Security
Best in #Reactive Programming
Average in #Reactive Programming
uvicorn Security
Best in #Reactive Programming
Average in #Reactive Programming

license License

  • uvicorn is licensed under the BSD-3-Clause License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.
uvicorn License
Best in #Reactive Programming
Average in #Reactive Programming
uvicorn License
Best in #Reactive Programming
Average in #Reactive Programming

buildReuse

  • uvicorn releases are available to install and integrate.
  • Deployable package is available in PyPI.
  • Build file is available. You can build the component from source.
  • Installation instructions, examples and code snippets are available.
  • It has 6960 lines of code, 557 functions and 67 files.
  • It has high code complexity. Code complexity directly impacts maintainability of the code.
uvicorn Reuse
Best in #Reactive Programming
Average in #Reactive Programming
uvicorn Reuse
Best in #Reactive Programming
Average in #Reactive Programming
Top functions reviewed by kandi - BETA

kandi has reviewed uvicorn and discovered the below as its top functions. This is intended to give you an instant insight into uvicorn implemented functionality, and help decide if they suit your requirements.

  • Sends an ASGI message .
  • Handle incoming events .
  • Load ssl context .
  • Handle http transport .
  • Sends an ASGi message .
  • Checks if an entry should be watched .
  • Handles the upgrade request .
  • Builds the environ environment .
  • Log the started message .
  • Resolves a list of directories that should be reloaded .

uvicorn Key Features

An ASGI web server, for Python. 🦄

Quickstart

copy iconCopydownload iconDownload
$ pip install uvicorn

Daphne

copy iconCopydownload iconDownload
$ pip install daphne
$ daphne app:App

Hypercorn

copy iconCopydownload iconDownload
$ pip install hypercorn
$ hypercorn app:App

Not able to connect to websocket using Nginx and Uvicorn

copy iconCopydownload iconDownload
pip uninstall uvicorn
pip install 'uvicorn[standard]'

Lots of "Uncaught signal: 6" errors in Cloud Run

copy iconCopydownload iconDownload
CMD ["uvicorn", "app.__main__:app", "--host", "0.0.0.0", "--port", "8080"]

uvicorn [fastapi] python run both HTTP and HTTPS

copy iconCopydownload iconDownload
if __name__ == '__main__':
    Popen(['python', '-m', 'https_redirect'])  # Add this
    uvicorn.run(
        'main:app', port=443, host='0.0.0.0',
        reload=True, reload_dirs=['html_files'],
        ssl_keyfile='/etc/letsencrypt/live/my_domain/privkey.pem',
        ssl_certfile='/etc/letsencrypt/live/my_domain/fullchain.pem')
import uvicorn
from fastapi import FastAPI
from starlette.requests import Request
from starlette.responses import RedirectResponse

app = FastAPI()


@app.route('/{_:path}')
async def https_redirect(request: Request):
    return RedirectResponse(request.url.replace(scheme='https'))

if __name__ == '__main__':
    uvicorn.run('https_redirect:app', port=80, host='0.0.0.0')
-----------------------
if __name__ == '__main__':
    Popen(['python', '-m', 'https_redirect'])  # Add this
    uvicorn.run(
        'main:app', port=443, host='0.0.0.0',
        reload=True, reload_dirs=['html_files'],
        ssl_keyfile='/etc/letsencrypt/live/my_domain/privkey.pem',
        ssl_certfile='/etc/letsencrypt/live/my_domain/fullchain.pem')
import uvicorn
from fastapi import FastAPI
from starlette.requests import Request
from starlette.responses import RedirectResponse

app = FastAPI()


@app.route('/{_:path}')
async def https_redirect(request: Request):
    return RedirectResponse(request.url.replace(scheme='https'))

if __name__ == '__main__':
    uvicorn.run('https_redirect:app', port=80, host='0.0.0.0')
-----------------------
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
app.add_middleware(HTTPSRedirectMiddleware)

how to make the sqlalchemy async session(Async Session) generator as class-base?

copy iconCopydownload iconDownload
import logging

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

Base = declarative_base()


class DBManager:
    def __init__(self):
        self.SQLALCHEMY_DATABASE_URL = None
        self.config_reader_instance = None
        self.engine = None
        self.session_factory = None
        self.Base = declarative_base()
        self.logger_handler_instance = None

    def initialize(self, config_reader_instance, logger_handler_instance):
        self.logger_handler_instance = logger_handler_instance
        self.config_reader_instance = config_reader_instance
        self.SQLALCHEMY_DATABASE_URL = "mysql+asyncmy://{0}:{1}@{2}:{3}/{4}".format(
            self.config_reader_instance.DB_INFO['db_username'], self.config_reader_instance.DB_INFO['db_password'],
            self.config_reader_instance.DB_INFO['db_hostname'], self.config_reader_instance.DB_INFO['db_port'],
            self.config_reader_instance.DB_INFO['db_name'])
        self.engine = create_async_engine(self.SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, pool_size=30,
                                          max_overflow=30, echo_pool=True, echo=False,
                                          pool_recycle=3600)  # recycle every hour
        DBManager.Base = declarative_base()
        self.session_factory = scoped_session(sessionmaker(
            self.engine, class_=AsyncSession, expire_on_commit=False
        ))

    def get_db_session(self):
        session = self.session_factory()
        try:
            yield session
        except Exception as e:
            self.logger_handler_instance.log(__name__, logging.FATAL,
                                             'Session rollback because of exception')
            self.logger_handler_instance.log(__name__, logging.FATAL, e)
            session.rollback()
            raise
        finally:
            session.close()

    async def init_models(self):
        async with self.engine.begin() as conn:
            await conn.run_sync(Base.metadata.drop_all)
            await conn.run_sync(Base.metadata.create_all)
class BackgroundRunnable:
    def __init__(self):
        self.instance_manger = None
        self.core_process_instance = None
        self.conf_reader_instance = None
        self.process_id = None
        self.process_name = "BTC"

    def initialize(self, instance_manager: InstanceManager):
        self.instance_manger = instance_manager
        return self

    def set_process_info(self, process_name):
        self.process_id = os.getpid()
        self.process_name = process_name

    async def run_main(self):
        self.instance_manger.logger_handler_instance.write_log(__name__, logging.INFO,
                                                               "Background Thread is start")
        self.session: AsyncSession = next(self.instance_manger.db_instance.get_db_session())
        results = await CryptoCoinService(CryptoCoinRepository(self.session)).get_coin(
            self.instance_manger.config_reader_instance.BTC_INFO['BTC_COIN'])
        print(results)
"""Repositories module."""
from contextlib import AbstractContextManager
from typing import Callable

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import class_mapper, Session

from db.models.models import CryptoCoinModel


class CryptoCoinRepository:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session

    async def get_all(self, coin) -> bool:
        results = await self.session.execute(
            select(CryptoCoinModel._id).where(CryptoCoinModel._symbol == coin))
        results = results.fetchall()
        if len(results) == 0:
            return False
        else:
            return True

    def serialize(self, model):
        """Transforms a model into a dictionary which can be dumped to JSON."""
        # first we get the names of all the columns on your model
        columns = [c.key for c in class_mapper(model.__class__).columns]
        # then we return their values in a dict
        return dict((c, getattr(model, '_' + c)) for c in columns)


class NotFoundError(Exception):
    symbol: str

    def __init__(self):
        super().__init__(f'{self._symobl} not found,please add this coin to db')


class CryptoCoinNotFoundError(NotFoundError):
    # entity_name: str = 'User'
    pass
from fastapi import APIRouter, Depends, Request, Response, FastAPI, status
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

from coin_server.background_thread import BackgroundRunnable
from coin_server.core_process import CoreProcess
from core.instance_manager import InstanceManager
from db.database import DBManager
from db.repository.crypto_coin_repository import CryptoCoinRepository
from db.services.crypto_coin_service import CryptoCoinService

deposit_Router = APIRouter()

instance_manager = InstanceManager()
instance_manager.initialize()
db_instance = DBManager()
db_instance.initialize(instance_manager.config_reader_instance, instance_manager.logger_handler_instance)


@deposit_Router.post('/')
async def index(request: Request, session: AsyncSession = Depends(db_instance.get_db_session)):
    results = await CryptoCoinService(CryptoCoinRepository(session)).get_coin()
    print(results)

deposit_app = FastAPI()

@deposit_app.on_event('startup')
async def app_startup():
    background_runnable = BackgroundRunnable()
    background_runnable.initialize(instance_manager)
    asyncio.create_task(background_runnable.run_main())
    # asyncio.create_task(BackgroundRunnable().initialize(instance_manager).run_main())

deposit_app.include_router(deposit_Router)
-----------------------
import logging

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

Base = declarative_base()


class DBManager:
    def __init__(self):
        self.SQLALCHEMY_DATABASE_URL = None
        self.config_reader_instance = None
        self.engine = None
        self.session_factory = None
        self.Base = declarative_base()
        self.logger_handler_instance = None

    def initialize(self, config_reader_instance, logger_handler_instance):
        self.logger_handler_instance = logger_handler_instance
        self.config_reader_instance = config_reader_instance
        self.SQLALCHEMY_DATABASE_URL = "mysql+asyncmy://{0}:{1}@{2}:{3}/{4}".format(
            self.config_reader_instance.DB_INFO['db_username'], self.config_reader_instance.DB_INFO['db_password'],
            self.config_reader_instance.DB_INFO['db_hostname'], self.config_reader_instance.DB_INFO['db_port'],
            self.config_reader_instance.DB_INFO['db_name'])
        self.engine = create_async_engine(self.SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, pool_size=30,
                                          max_overflow=30, echo_pool=True, echo=False,
                                          pool_recycle=3600)  # recycle every hour
        DBManager.Base = declarative_base()
        self.session_factory = scoped_session(sessionmaker(
            self.engine, class_=AsyncSession, expire_on_commit=False
        ))

    def get_db_session(self):
        session = self.session_factory()
        try:
            yield session
        except Exception as e:
            self.logger_handler_instance.log(__name__, logging.FATAL,
                                             'Session rollback because of exception')
            self.logger_handler_instance.log(__name__, logging.FATAL, e)
            session.rollback()
            raise
        finally:
            session.close()

    async def init_models(self):
        async with self.engine.begin() as conn:
            await conn.run_sync(Base.metadata.drop_all)
            await conn.run_sync(Base.metadata.create_all)
class BackgroundRunnable:
    def __init__(self):
        self.instance_manger = None
        self.core_process_instance = None
        self.conf_reader_instance = None
        self.process_id = None
        self.process_name = "BTC"

    def initialize(self, instance_manager: InstanceManager):
        self.instance_manger = instance_manager
        return self

    def set_process_info(self, process_name):
        self.process_id = os.getpid()
        self.process_name = process_name

    async def run_main(self):
        self.instance_manger.logger_handler_instance.write_log(__name__, logging.INFO,
                                                               "Background Thread is start")
        self.session: AsyncSession = next(self.instance_manger.db_instance.get_db_session())
        results = await CryptoCoinService(CryptoCoinRepository(self.session)).get_coin(
            self.instance_manger.config_reader_instance.BTC_INFO['BTC_COIN'])
        print(results)
"""Repositories module."""
from contextlib import AbstractContextManager
from typing import Callable

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import class_mapper, Session

from db.models.models import CryptoCoinModel


class CryptoCoinRepository:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session

    async def get_all(self, coin) -> bool:
        results = await self.session.execute(
            select(CryptoCoinModel._id).where(CryptoCoinModel._symbol == coin))
        results = results.fetchall()
        if len(results) == 0:
            return False
        else:
            return True

    def serialize(self, model):
        """Transforms a model into a dictionary which can be dumped to JSON."""
        # first we get the names of all the columns on your model
        columns = [c.key for c in class_mapper(model.__class__).columns]
        # then we return their values in a dict
        return dict((c, getattr(model, '_' + c)) for c in columns)


class NotFoundError(Exception):
    symbol: str

    def __init__(self):
        super().__init__(f'{self._symobl} not found,please add this coin to db')


class CryptoCoinNotFoundError(NotFoundError):
    # entity_name: str = 'User'
    pass
from fastapi import APIRouter, Depends, Request, Response, FastAPI, status
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

from coin_server.background_thread import BackgroundRunnable
from coin_server.core_process import CoreProcess
from core.instance_manager import InstanceManager
from db.database import DBManager
from db.repository.crypto_coin_repository import CryptoCoinRepository
from db.services.crypto_coin_service import CryptoCoinService

deposit_Router = APIRouter()

instance_manager = InstanceManager()
instance_manager.initialize()
db_instance = DBManager()
db_instance.initialize(instance_manager.config_reader_instance, instance_manager.logger_handler_instance)


@deposit_Router.post('/')
async def index(request: Request, session: AsyncSession = Depends(db_instance.get_db_session)):
    results = await CryptoCoinService(CryptoCoinRepository(session)).get_coin()
    print(results)

deposit_app = FastAPI()

@deposit_app.on_event('startup')
async def app_startup():
    background_runnable = BackgroundRunnable()
    background_runnable.initialize(instance_manager)
    asyncio.create_task(background_runnable.run_main())
    # asyncio.create_task(BackgroundRunnable().initialize(instance_manager).run_main())

deposit_app.include_router(deposit_Router)
-----------------------
import logging

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

Base = declarative_base()


class DBManager:
    def __init__(self):
        self.SQLALCHEMY_DATABASE_URL = None
        self.config_reader_instance = None
        self.engine = None
        self.session_factory = None
        self.Base = declarative_base()
        self.logger_handler_instance = None

    def initialize(self, config_reader_instance, logger_handler_instance):
        self.logger_handler_instance = logger_handler_instance
        self.config_reader_instance = config_reader_instance
        self.SQLALCHEMY_DATABASE_URL = "mysql+asyncmy://{0}:{1}@{2}:{3}/{4}".format(
            self.config_reader_instance.DB_INFO['db_username'], self.config_reader_instance.DB_INFO['db_password'],
            self.config_reader_instance.DB_INFO['db_hostname'], self.config_reader_instance.DB_INFO['db_port'],
            self.config_reader_instance.DB_INFO['db_name'])
        self.engine = create_async_engine(self.SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, pool_size=30,
                                          max_overflow=30, echo_pool=True, echo=False,
                                          pool_recycle=3600)  # recycle every hour
        DBManager.Base = declarative_base()
        self.session_factory = scoped_session(sessionmaker(
            self.engine, class_=AsyncSession, expire_on_commit=False
        ))

    def get_db_session(self):
        session = self.session_factory()
        try:
            yield session
        except Exception as e:
            self.logger_handler_instance.log(__name__, logging.FATAL,
                                             'Session rollback because of exception')
            self.logger_handler_instance.log(__name__, logging.FATAL, e)
            session.rollback()
            raise
        finally:
            session.close()

    async def init_models(self):
        async with self.engine.begin() as conn:
            await conn.run_sync(Base.metadata.drop_all)
            await conn.run_sync(Base.metadata.create_all)
class BackgroundRunnable:
    def __init__(self):
        self.instance_manger = None
        self.core_process_instance = None
        self.conf_reader_instance = None
        self.process_id = None
        self.process_name = "BTC"

    def initialize(self, instance_manager: InstanceManager):
        self.instance_manger = instance_manager
        return self

    def set_process_info(self, process_name):
        self.process_id = os.getpid()
        self.process_name = process_name

    async def run_main(self):
        self.instance_manger.logger_handler_instance.write_log(__name__, logging.INFO,
                                                               "Background Thread is start")
        self.session: AsyncSession = next(self.instance_manger.db_instance.get_db_session())
        results = await CryptoCoinService(CryptoCoinRepository(self.session)).get_coin(
            self.instance_manger.config_reader_instance.BTC_INFO['BTC_COIN'])
        print(results)
"""Repositories module."""
from contextlib import AbstractContextManager
from typing import Callable

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import class_mapper, Session

from db.models.models import CryptoCoinModel


class CryptoCoinRepository:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session

    async def get_all(self, coin) -> bool:
        results = await self.session.execute(
            select(CryptoCoinModel._id).where(CryptoCoinModel._symbol == coin))
        results = results.fetchall()
        if len(results) == 0:
            return False
        else:
            return True

    def serialize(self, model):
        """Transforms a model into a dictionary which can be dumped to JSON."""
        # first we get the names of all the columns on your model
        columns = [c.key for c in class_mapper(model.__class__).columns]
        # then we return their values in a dict
        return dict((c, getattr(model, '_' + c)) for c in columns)


class NotFoundError(Exception):
    symbol: str

    def __init__(self):
        super().__init__(f'{self._symobl} not found,please add this coin to db')


class CryptoCoinNotFoundError(NotFoundError):
    # entity_name: str = 'User'
    pass
from fastapi import APIRouter, Depends, Request, Response, FastAPI, status
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

from coin_server.background_thread import BackgroundRunnable
from coin_server.core_process import CoreProcess
from core.instance_manager import InstanceManager
from db.database import DBManager
from db.repository.crypto_coin_repository import CryptoCoinRepository
from db.services.crypto_coin_service import CryptoCoinService

deposit_Router = APIRouter()

instance_manager = InstanceManager()
instance_manager.initialize()
db_instance = DBManager()
db_instance.initialize(instance_manager.config_reader_instance, instance_manager.logger_handler_instance)


@deposit_Router.post('/')
async def index(request: Request, session: AsyncSession = Depends(db_instance.get_db_session)):
    results = await CryptoCoinService(CryptoCoinRepository(session)).get_coin()
    print(results)

deposit_app = FastAPI()

@deposit_app.on_event('startup')
async def app_startup():
    background_runnable = BackgroundRunnable()
    background_runnable.initialize(instance_manager)
    asyncio.create_task(background_runnable.run_main())
    # asyncio.create_task(BackgroundRunnable().initialize(instance_manager).run_main())

deposit_app.include_router(deposit_Router)
-----------------------
import logging

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

Base = declarative_base()


class DBManager:
    def __init__(self):
        self.SQLALCHEMY_DATABASE_URL = None
        self.config_reader_instance = None
        self.engine = None
        self.session_factory = None
        self.Base = declarative_base()
        self.logger_handler_instance = None

    def initialize(self, config_reader_instance, logger_handler_instance):
        self.logger_handler_instance = logger_handler_instance
        self.config_reader_instance = config_reader_instance
        self.SQLALCHEMY_DATABASE_URL = "mysql+asyncmy://{0}:{1}@{2}:{3}/{4}".format(
            self.config_reader_instance.DB_INFO['db_username'], self.config_reader_instance.DB_INFO['db_password'],
            self.config_reader_instance.DB_INFO['db_hostname'], self.config_reader_instance.DB_INFO['db_port'],
            self.config_reader_instance.DB_INFO['db_name'])
        self.engine = create_async_engine(self.SQLALCHEMY_DATABASE_URL, pool_pre_ping=True, pool_size=30,
                                          max_overflow=30, echo_pool=True, echo=False,
                                          pool_recycle=3600)  # recycle every hour
        DBManager.Base = declarative_base()
        self.session_factory = scoped_session(sessionmaker(
            self.engine, class_=AsyncSession, expire_on_commit=False
        ))

    def get_db_session(self):
        session = self.session_factory()
        try:
            yield session
        except Exception as e:
            self.logger_handler_instance.log(__name__, logging.FATAL,
                                             'Session rollback because of exception')
            self.logger_handler_instance.log(__name__, logging.FATAL, e)
            session.rollback()
            raise
        finally:
            session.close()

    async def init_models(self):
        async with self.engine.begin() as conn:
            await conn.run_sync(Base.metadata.drop_all)
            await conn.run_sync(Base.metadata.create_all)
class BackgroundRunnable:
    def __init__(self):
        self.instance_manger = None
        self.core_process_instance = None
        self.conf_reader_instance = None
        self.process_id = None
        self.process_name = "BTC"

    def initialize(self, instance_manager: InstanceManager):
        self.instance_manger = instance_manager
        return self

    def set_process_info(self, process_name):
        self.process_id = os.getpid()
        self.process_name = process_name

    async def run_main(self):
        self.instance_manger.logger_handler_instance.write_log(__name__, logging.INFO,
                                                               "Background Thread is start")
        self.session: AsyncSession = next(self.instance_manger.db_instance.get_db_session())
        results = await CryptoCoinService(CryptoCoinRepository(self.session)).get_coin(
            self.instance_manger.config_reader_instance.BTC_INFO['BTC_COIN'])
        print(results)
"""Repositories module."""
from contextlib import AbstractContextManager
from typing import Callable

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import class_mapper, Session

from db.models.models import CryptoCoinModel


class CryptoCoinRepository:
    def __init__(self, session: AsyncSession) -> None:
        self.session = session

    async def get_all(self, coin) -> bool:
        results = await self.session.execute(
            select(CryptoCoinModel._id).where(CryptoCoinModel._symbol == coin))
        results = results.fetchall()
        if len(results) == 0:
            return False
        else:
            return True

    def serialize(self, model):
        """Transforms a model into a dictionary which can be dumped to JSON."""
        # first we get the names of all the columns on your model
        columns = [c.key for c in class_mapper(model.__class__).columns]
        # then we return their values in a dict
        return dict((c, getattr(model, '_' + c)) for c in columns)


class NotFoundError(Exception):
    symbol: str

    def __init__(self):
        super().__init__(f'{self._symobl} not found,please add this coin to db')


class CryptoCoinNotFoundError(NotFoundError):
    # entity_name: str = 'User'
    pass
from fastapi import APIRouter, Depends, Request, Response, FastAPI, status
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession

from coin_server.background_thread import BackgroundRunnable
from coin_server.core_process import CoreProcess
from core.instance_manager import InstanceManager
from db.database import DBManager
from db.repository.crypto_coin_repository import CryptoCoinRepository
from db.services.crypto_coin_service import CryptoCoinService

deposit_Router = APIRouter()

instance_manager = InstanceManager()
instance_manager.initialize()
db_instance = DBManager()
db_instance.initialize(instance_manager.config_reader_instance, instance_manager.logger_handler_instance)


@deposit_Router.post('/')
async def index(request: Request, session: AsyncSession = Depends(db_instance.get_db_session)):
    results = await CryptoCoinService(CryptoCoinRepository(session)).get_coin()
    print(results)

deposit_app = FastAPI()

@deposit_app.on_event('startup')
async def app_startup():
    background_runnable = BackgroundRunnable()
    background_runnable.initialize(instance_manager)
    asyncio.create_task(background_runnable.run_main())
    # asyncio.create_task(BackgroundRunnable().initialize(instance_manager).run_main())

deposit_app.include_router(deposit_Router)

Uvicorn async workers are still working synchronously

copy iconCopydownload iconDownload
gunicorn MyService.asgi:application -k uvicorn.workers.UvicornWorker -w 10
-----------------------
'django.request': {
    'handlers': ['console'],
    'level': 'DEBUG',
},
class ApiLoggerMiddleware(MiddlewareMixin):
    TOO_BIG_FOR_LOG_BYTES = 2 * 1024

    def __init__(self, get_response):
        # The get_response callable is provided by Django, it is a function
        # that takes a request and returns a response. Plainly put, once we're
        # done with the incoming request, we need to pass it along to get the
        # response which we need to ultimately return.
        super().__init__(get_response)  # +
        self._get_response = get_response
        self.logger = logging.getLogger('api')
        self.pid = os.getpid()
        # self.request_time = None   # -
        # self.response_time = None  # -

    # def __call__(self, request: HttpRequest) -> HttpResponse:  # -
    #     common_data = self.on_request(request)                 # -
    #     response = self._get_response(request)                 # -
    #     self.on_response(response, common_data)                # -
    #     return response                                        # -

    def truncate_body(self, request: HttpRequest) -> str:
        return f"{request.body[:self.TOO_BIG_FOR_LOG_BYTES]}"

    # def on_request(self, request: HttpRequest) -> List[str]:  # -
    def process_request(self, request: HttpRequest) -> None:    # +
        # self.request_time = timezone.now()   # -
        request.request_time = timezone.now()  # +

        remote_address = self.get_remote_address(request)
        user_agent = request.headers.get('User-Agent') or ''
        customer_uuid = self.get_customer_from_request_auth(request)
        method = request.method
        uri = request.get_raw_uri()

        common = [
            remote_address,
            user_agent,
            customer_uuid,
            method,
            uri
        ]

        in_line = [
            "IN",
            str(self.pid),
            # str(self.request_time),   # -
            str(request.request_time),  # +
        ] + common + [
            self.truncate_body(request)
        ]

        self.logger.info(', '.join(in_line))
        # return common          # -
        request.common = common  # +
        return None              # +

    # def on_response(self, response: HttpResponse, common: List[str]) -> None:                # -
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:  # +
        # self.response_time = timezone.now()  # -
        response_time = timezone.now()         # +

        out_line = [
            "OUT",
            str(self.pid),
            # str(self.response_time)  # -
            str(response_time)         # +
            # ] + common + [                    # -
        ] + getattr(request, 'common', []) + [  # +
            # str(self.response_time - self.request_time),             # -
            str(response_time - getattr(request, 'request_time', 0)),  # +
            str(response.status_code),
        ]
        self.logger.info(", ".join(out_line))
        return response  # +

    @classmethod
    def get_customer_from_request_auth(cls, request: HttpRequest) -> str:
        token = request.headers.get('Authorization')
        if not token:
            return 'no token'
        try:
            payload = BaseAuthenticationService.validate_access_token(token)
            return payload.get('amsOrganizationId', '')
        except Exception:
            return 'unknown'

    @classmethod
    def get_remote_address(cls, request: HttpRequest) -> str:
        if 'X-Forwarded-For' in request.headers:
            # in case the request comes in through a proxy, the remote address
            # will be just the last proxy that passed it along, that's why we
            # have to get the remote from X-Forwarded-For
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            addresses = request.headers['X-Forwarded-For'].split(',')
            client = addresses[0]
            return client
        else:
            return request.META.get('REMOTE_ADDR', '')
-----------------------
'django.request': {
    'handlers': ['console'],
    'level': 'DEBUG',
},
class ApiLoggerMiddleware(MiddlewareMixin):
    TOO_BIG_FOR_LOG_BYTES = 2 * 1024

    def __init__(self, get_response):
        # The get_response callable is provided by Django, it is a function
        # that takes a request and returns a response. Plainly put, once we're
        # done with the incoming request, we need to pass it along to get the
        # response which we need to ultimately return.
        super().__init__(get_response)  # +
        self._get_response = get_response
        self.logger = logging.getLogger('api')
        self.pid = os.getpid()
        # self.request_time = None   # -
        # self.response_time = None  # -

    # def __call__(self, request: HttpRequest) -> HttpResponse:  # -
    #     common_data = self.on_request(request)                 # -
    #     response = self._get_response(request)                 # -
    #     self.on_response(response, common_data)                # -
    #     return response                                        # -

    def truncate_body(self, request: HttpRequest) -> str:
        return f"{request.body[:self.TOO_BIG_FOR_LOG_BYTES]}"

    # def on_request(self, request: HttpRequest) -> List[str]:  # -
    def process_request(self, request: HttpRequest) -> None:    # +
        # self.request_time = timezone.now()   # -
        request.request_time = timezone.now()  # +

        remote_address = self.get_remote_address(request)
        user_agent = request.headers.get('User-Agent') or ''
        customer_uuid = self.get_customer_from_request_auth(request)
        method = request.method
        uri = request.get_raw_uri()

        common = [
            remote_address,
            user_agent,
            customer_uuid,
            method,
            uri
        ]

        in_line = [
            "IN",
            str(self.pid),
            # str(self.request_time),   # -
            str(request.request_time),  # +
        ] + common + [
            self.truncate_body(request)
        ]

        self.logger.info(', '.join(in_line))
        # return common          # -
        request.common = common  # +
        return None              # +

    # def on_response(self, response: HttpResponse, common: List[str]) -> None:                # -
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:  # +
        # self.response_time = timezone.now()  # -
        response_time = timezone.now()         # +

        out_line = [
            "OUT",
            str(self.pid),
            # str(self.response_time)  # -
            str(response_time)         # +
            # ] + common + [                    # -
        ] + getattr(request, 'common', []) + [  # +
            # str(self.response_time - self.request_time),             # -
            str(response_time - getattr(request, 'request_time', 0)),  # +
            str(response.status_code),
        ]
        self.logger.info(", ".join(out_line))
        return response  # +

    @classmethod
    def get_customer_from_request_auth(cls, request: HttpRequest) -> str:
        token = request.headers.get('Authorization')
        if not token:
            return 'no token'
        try:
            payload = BaseAuthenticationService.validate_access_token(token)
            return payload.get('amsOrganizationId', '')
        except Exception:
            return 'unknown'

    @classmethod
    def get_remote_address(cls, request: HttpRequest) -> str:
        if 'X-Forwarded-For' in request.headers:
            # in case the request comes in through a proxy, the remote address
            # will be just the last proxy that passed it along, that's why we
            # have to get the remote from X-Forwarded-For
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            addresses = request.headers['X-Forwarded-For'].split(',')
            client = addresses[0]
            return client
        else:
            return request.META.get('REMOTE_ADDR', '')

FastAPI - Pydantic - Value Error Raises Internal Server Error

copy iconCopydownload iconDownload
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse


@app.exception_handler(ValueError)
async def value_error_exception_handler(request: Request, exc: ValueError):
    return JSONResponse(
        status_code=400,
        content={"message": str(exc)},
    )
{
    "message": "Value Must be within range (0,1000000)"
}
-----------------------
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse


@app.exception_handler(ValueError)
async def value_error_exception_handler(request: Request, exc: ValueError):
    return JSONResponse(
        status_code=400,
        content={"message": str(exc)},
    )
{
    "message": "Value Must be within range (0,1000000)"
}
-----------------------
from fastapi import Depends, FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.responses import JSONResponse
from pydantic import BaseModel, conint

class RankInput(BaseModel):
    # Constrained integer, must be greater that or equal to 0
    # and less than or equal to 1 million.
    rank: conint(ge=0, le=1_000_000)

async def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):

    validation_errors = exc.errors()
    for err in validation_errors:
        # You could check for other things here as well, e.g. the error type.
        if "rank" in err["loc"]:
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content={"message": "Rank must be in range [0, 1000000]."}
            )

    # Default response in every other case.
    return await request_validation_exception_handler(request, exc)

def get_info_by_rank(rank):
    return rank


app = FastAPI(
    exception_handlers={RequestValidationError: rank_out_of_bound_handler},
)

@app.get('/rank/{rank}')
async def get_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/rank/1"
HTTP/1.1 200 OK
date: Sat, 28 Aug 2021 20:47:58 GMT
server: uvicorn
content-length: 1
content-type: application/json

1
$  curl -i "http://127.0.0.1:8000/rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:24 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
$ curl -i "http://127.0.0.1:8000/rank/1000001"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:51 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
@app.get('/other-rank/{rank}')
async def get_other_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/other-rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:54:16 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
-----------------------
from fastapi import Depends, FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.responses import JSONResponse
from pydantic import BaseModel, conint

class RankInput(BaseModel):
    # Constrained integer, must be greater that or equal to 0
    # and less than or equal to 1 million.
    rank: conint(ge=0, le=1_000_000)

async def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):

    validation_errors = exc.errors()
    for err in validation_errors:
        # You could check for other things here as well, e.g. the error type.
        if "rank" in err["loc"]:
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content={"message": "Rank must be in range [0, 1000000]."}
            )

    # Default response in every other case.
    return await request_validation_exception_handler(request, exc)

def get_info_by_rank(rank):
    return rank


app = FastAPI(
    exception_handlers={RequestValidationError: rank_out_of_bound_handler},
)

@app.get('/rank/{rank}')
async def get_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/rank/1"
HTTP/1.1 200 OK
date: Sat, 28 Aug 2021 20:47:58 GMT
server: uvicorn
content-length: 1
content-type: application/json

1
$  curl -i "http://127.0.0.1:8000/rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:24 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
$ curl -i "http://127.0.0.1:8000/rank/1000001"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:51 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
@app.get('/other-rank/{rank}')
async def get_other_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/other-rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:54:16 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
-----------------------
from fastapi import Depends, FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.responses import JSONResponse
from pydantic import BaseModel, conint

class RankInput(BaseModel):
    # Constrained integer, must be greater that or equal to 0
    # and less than or equal to 1 million.
    rank: conint(ge=0, le=1_000_000)

async def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):

    validation_errors = exc.errors()
    for err in validation_errors:
        # You could check for other things here as well, e.g. the error type.
        if "rank" in err["loc"]:
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content={"message": "Rank must be in range [0, 1000000]."}
            )

    # Default response in every other case.
    return await request_validation_exception_handler(request, exc)

def get_info_by_rank(rank):
    return rank


app = FastAPI(
    exception_handlers={RequestValidationError: rank_out_of_bound_handler},
)

@app.get('/rank/{rank}')
async def get_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/rank/1"
HTTP/1.1 200 OK
date: Sat, 28 Aug 2021 20:47:58 GMT
server: uvicorn
content-length: 1
content-type: application/json

1
$  curl -i "http://127.0.0.1:8000/rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:24 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
$ curl -i "http://127.0.0.1:8000/rank/1000001"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:51 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
@app.get('/other-rank/{rank}')
async def get_other_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/other-rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:54:16 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
-----------------------
from fastapi import Depends, FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.responses import JSONResponse
from pydantic import BaseModel, conint

class RankInput(BaseModel):
    # Constrained integer, must be greater that or equal to 0
    # and less than or equal to 1 million.
    rank: conint(ge=0, le=1_000_000)

async def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):

    validation_errors = exc.errors()
    for err in validation_errors:
        # You could check for other things here as well, e.g. the error type.
        if "rank" in err["loc"]:
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content={"message": "Rank must be in range [0, 1000000]."}
            )

    # Default response in every other case.
    return await request_validation_exception_handler(request, exc)

def get_info_by_rank(rank):
    return rank


app = FastAPI(
    exception_handlers={RequestValidationError: rank_out_of_bound_handler},
)

@app.get('/rank/{rank}')
async def get_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/rank/1"
HTTP/1.1 200 OK
date: Sat, 28 Aug 2021 20:47:58 GMT
server: uvicorn
content-length: 1
content-type: application/json

1
$  curl -i "http://127.0.0.1:8000/rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:24 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
$ curl -i "http://127.0.0.1:8000/rank/1000001"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:51 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
@app.get('/other-rank/{rank}')
async def get_other_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/other-rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:54:16 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
-----------------------
from fastapi import Depends, FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.responses import JSONResponse
from pydantic import BaseModel, conint

class RankInput(BaseModel):
    # Constrained integer, must be greater that or equal to 0
    # and less than or equal to 1 million.
    rank: conint(ge=0, le=1_000_000)

async def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):

    validation_errors = exc.errors()
    for err in validation_errors:
        # You could check for other things here as well, e.g. the error type.
        if "rank" in err["loc"]:
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content={"message": "Rank must be in range [0, 1000000]."}
            )

    # Default response in every other case.
    return await request_validation_exception_handler(request, exc)

def get_info_by_rank(rank):
    return rank


app = FastAPI(
    exception_handlers={RequestValidationError: rank_out_of_bound_handler},
)

@app.get('/rank/{rank}')
async def get_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/rank/1"
HTTP/1.1 200 OK
date: Sat, 28 Aug 2021 20:47:58 GMT
server: uvicorn
content-length: 1
content-type: application/json

1
$  curl -i "http://127.0.0.1:8000/rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:24 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
$ curl -i "http://127.0.0.1:8000/rank/1000001"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:51 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
@app.get('/other-rank/{rank}')
async def get_other_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/other-rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:54:16 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
-----------------------
from fastapi import Depends, FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.exception_handlers import request_validation_exception_handler
from fastapi.responses import JSONResponse
from pydantic import BaseModel, conint

class RankInput(BaseModel):
    # Constrained integer, must be greater that or equal to 0
    # and less than or equal to 1 million.
    rank: conint(ge=0, le=1_000_000)

async def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):

    validation_errors = exc.errors()
    for err in validation_errors:
        # You could check for other things here as well, e.g. the error type.
        if "rank" in err["loc"]:
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content={"message": "Rank must be in range [0, 1000000]."}
            )

    # Default response in every other case.
    return await request_validation_exception_handler(request, exc)

def get_info_by_rank(rank):
    return rank


app = FastAPI(
    exception_handlers={RequestValidationError: rank_out_of_bound_handler},
)

@app.get('/rank/{rank}')
async def get_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/rank/1"
HTTP/1.1 200 OK
date: Sat, 28 Aug 2021 20:47:58 GMT
server: uvicorn
content-length: 1
content-type: application/json

1
$  curl -i "http://127.0.0.1:8000/rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:24 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
$ curl -i "http://127.0.0.1:8000/rank/1000001"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:48:51 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}
@app.get('/other-rank/{rank}')
async def get_other_rank(value: RankInput = Depends()):
    result = get_info_by_rank(value.rank)
    return result
$ curl -i "http://127.0.0.1:8000/other-rank/-1"
HTTP/1.1 400 Bad Request
date: Sat, 28 Aug 2021 20:54:16 GMT
server: uvicorn
content-length: 49
content-type: application/json

{"message":"Rank must be in range [0, 1000000]."}

Django Channels: WebSocket messages are not sent in production

copy iconCopydownload iconDownload
     location /ws/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $http_host;
        proxy_pass http://uvicorn;
    }

FastApi sqlalchemy Connection was closed in the middle of operation

copy iconCopydownload iconDownload
tcp_keepalives_idle = 600               # TCP_KEEPIDLE, in seconds;
                                       # 0 selects the system default
tcp_keepalives_interval = 30            # TCP_KEEPINTVL, in seconds;
                                       # 0 selects the system default
tcp_keepalives_count = 10               # TCP_KEEPCNT;
                                       # 0 selects the system default
-----------------------
engine = create_engine(DB_URL, pool_pre_ping=True)

FastAPI, uvicorn.run() always create 3 instances, but I want it 1 instance

copy iconCopydownload iconDownload
import uvicorn

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=False, log_level="debug", debug=True,
                workers=1, limit_concurrency=1, limit_max_requests=1)

uvicorn main:app --host=0.0.0.0 --port=8000 --log-level=debug --limit-max-requests=1 --limit-concurrency=1
-----------------------
import uvicorn

if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=False, log_level="debug", debug=True,
                workers=1, limit_concurrency=1, limit_max_requests=1)

uvicorn main:app --host=0.0.0.0 --port=8000 --log-level=debug --limit-max-requests=1 --limit-concurrency=1

how do I make API request after deploying uvicorn via fastapi in mylaptop

copy iconCopydownload iconDownload
class JobTitle(BaseModel):
    title: List[str]
-----------------------
>>> result = requests.post(url, json=params)
>>> result
<Response [200]>
-----------------------
@app.post("/predict")
def predict(request: JobTitle):
    ...
result = requests.post(
    url,
    json={'title': ['Product Operations Software Engineer (DevOps / SRE)']}
)
-----------------------
@app.post("/predict")
def predict(request: JobTitle):
    ...
result = requests.post(
    url,
    json={'title': ['Product Operations Software Engineer (DevOps / SRE)']}
)

Community Discussions

Trending Discussions on uvicorn
  • Not able to connect to websocket using Nginx and Uvicorn
  • Lots of &quot;Uncaught signal: 6&quot; errors in Cloud Run
  • uvicorn [fastapi] python run both HTTP and HTTPS
  • how to make the sqlalchemy async session(Async Session) generator as class-base?
  • Uvicorn async workers are still working synchronously
  • FastAPI deploy in heroku giving an error h10
  • FastAPI - Pydantic - Value Error Raises Internal Server Error
  • Django Channels: WebSocket messages are not sent in production
  • FastApi sqlalchemy Connection was closed in the middle of operation
  • FastAPI, uvicorn.run() always create 3 instances, but I want it 1 instance
Trending Discussions on uvicorn

QUESTION

Not able to connect to websocket using Nginx and Uvicorn

Asked 2022-Mar-26 at 10:20

I built a docker container with Django, Uvicorn, Nginx and Redis, and am using django-channels but when I run this it says it cannot connect to the websocket and this is seen in the browser console:

WebSocket connection to 'ws://127.0.0.1:8080/ws/notifications/' failed

It is working fine when I use Django's runserver command for development but when I include Nginx and Uvicorn it breaks.

Entrypoint.sh:

gunicorn roomway.asgi:application --forwarded-allow-ips='*' --bind 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker

Nginx config:

upstream django {
    server app:8000;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 8080;

    location /static {
        alias /vol/static;
    }

    location /ws/ {
        proxy_pass http://0.0.0.0:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location / {
        proxy_pass http://django;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_redirect off;
        proxy_buffering off;
    }
}

settings.py:

CHANNEL_LAYERS={
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            'hosts': [('redis', 6379)],  #Redis port
        }
    }
}

The JS file which handles the socket:

var wsStart = "ws://"    
var webSocketEndpoint =  wsStart + window.location.host + '/ws/notifications/'
const notificationSocket = new WebSocket(webSocketEndpoint)

asgi.py:

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": AuthMiddlewareStack(
        URLRouter([
            url(r'^ws/notifications/', NotificationConsumer.as_asgi()),
            path("ws/<str:room_name>/", ChatConsumer.as_asgi())            
        ])
    )
})

Nginx throws this error with the above code:

[error] 23#23: *4 connect() failed (111: Connection refused) while connecting to upstream, server: , request: "GET /ws/notifications/ HTTP/1.1", upstream: "http://0.0.0.0:8000/ws/notifications/", host: "127.0.0.1:8080"

When I change the proxy_pass to http://django instead of 0.0.0.0, Nginx does not throw that error anymore but I get the same error on the console. Also this time Django throws these warnings:

[WARNING] Unsupported upgrade request.       
[WARNING] No supported WebSocket library detected. Please use 'pip install uvicorn[standard]', or install 'websockets' or 'wsproto' manually.

ANSWER

Answered 2022-Mar-26 at 10:20

As noted in a comment by Iain Shelvington, it seems like websockets are not included in the base install of uvicorn

pip uninstall uvicorn
pip install 'uvicorn[standard]'

Source https://stackoverflow.com/questions/68828128

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

Vulnerabilities

No vulnerabilities reported

Install uvicorn

This will install uvicorn with minimal (pure Python) dependencies. This will install uvicorn with "Cython-based" dependencies (where possible) and other "optional extras".
the event loop uvloop will be installed and used if possible.
the http protocol will be handled by httptools if possible.
the websocket protocol will be handled by websockets (should you want to use wsproto you'd need to install it manually) if possible.
the --reload flag in development mode will use watchgod.
windows users will have colorama installed for the colored logs.
python-dotenv will be installed should you want to use the --env-file option.
PyYAML will be installed to allow you to provide a .yaml file to --log-config, if desired.

Support

For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

DOWNLOAD this Library from

Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

Share this Page

share link
Consider Popular Reactive Programming Libraries
Compare Reactive Programming Libraries with Highest Support
Compare Reactive Programming Libraries with Highest Quality
Compare Reactive Programming Libraries with Highest Security
Compare Reactive Programming Libraries with Permissive License
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
over 430 million Knowledge Items
Find more libraries
Reuse Solution Kits and Libraries Curated by Popular Use Cases

Save this library and start creating your kit

  • © 2022 Open Weaver Inc.