I implemented some Custom Exceptions. And now I want to display the Exception name at the red box. Where can I set this value?
class CustomExceptionHandler(Exception):
def __init__(self, exception):
self.message = exception.message
self.status_code_number = exception.status_code_number
#app.exception_handler(CustomExceptionHandler)
async def data_processing_error_handler(request: Request, exc: CustomExceptionHandler):
return JSONResponse(
status_code=exc.status_code_number,
content=jsonable_encoder({exc.message}),
)
Related
I am trying to integrate rasa with gpt3, but not getting the proper response. Can help me out to look at my code and tell me issue.
def gpt3(text):
response = openai.Completion.create(
model="code-cushman-001",
# engine="ada",
prompt="\n\n" + text,
temperature=0,
logprobs=10,
max_tokens=150,
top_p=0,
frequency_penalty=0,
presence_penalty=0,
stop=[" \n\n"]
)
return response['choices'][0]['text']
action.py
class ActionDefaultFallback(Action):
def init(self):
# self.gpt3 = gpt3()
super()._init_()
def name(self) -> Text:
return "action_default_fallback"
async def run(self, dispatcher, tracker, domain):
query = tracker.latest_message['text']
dispatcher.utter_message(text=gpt3(query))
return [UserUtteranceReverted()]
Not able to understand the issue. Help me out to solve this.
Thanks
Hope this is resolved. In case someone following-up on this. Since the exact error is not provided not sure answer is correct but I was able to work this with very little modification to above code.
def gpt3(text):
try:
response = openai.Completion.create(
# model="text-davinci-003",
model="text-ada-001",
prompt="\n\n" + text + "?",
temperature=0,
logprobs=10,
max_tokens=100,
top_p=0,
frequency_penalty=0,
presence_penalty=0,
stop=[" \n\n"]
)
return response['choices'][0]['text']
except Exception as e:
logger.error('openai request failed')
actions.py
class ActionDefaultFallback(Action):
def init(self):
super().__init__()
def name(self) -> Text:
return "action_default_fallback"
async def run(self, dispatcher, tracker, domain):
query = tracker.latest_message['text']
return dispatcher.utter_message(text=gpt3(query))
I have a function, that adds a new record to DB and I need to test it:
def add_report_to_db(latitude, longitude, color: str, comment: str):
"""Add a new report to the DB."""
try:
report = Report(
latitude=float(latitude),
longitude=float(longitude),
color=color,
comment=comment,
ip=request.remote_addr,
)
db.session.add(report)
db.session.commit()
flash("Success!", category="success")
except Exception as e:
flash("Error." + str(e), category="error")
I do test it with this code below:
class BasicsTestCase(unittest.TestCase):
"""General test cases."""
def setUp(self):
"""Execute before unit test. Create an app and in memory DB."""
self.app = create_app("testing")
self.app_context = self.app.app_context()
self.app_context.push()
db.create_all()
self.current_map = folium.Map(location=(50.45, 30.52))
self.client = self.app.test_client(use_cookies=True)
report = Report(
latitude=50.45,
longitude=30.52,
color="red",
comment="comment",
ip="127.0.0.1",
)
db.session.add(report)
db.session.commit()
def tearDown(self):
"""Execute after unit test. Drop DB, session, app."""
db.session.remove()
db.drop_all()
self.app_context.pop()
def test_add_report_to_db(self):
"""Test add a new report to the DB."""
with current_app.test_request_context():
result = add_report_to_db(
latitude=50.45,
longitude="testing", # a purposeful error is here
color="red",
comment="comment",
)
self.assertIsNone(result) # test passed even with exception
self.assertRaises(not Exception, result) # I need someting like this
The problem is that even if exeption occurs, the function returns None and test passes.
How do I can check that there were no any exceptions?
My application has an AuthenticateService implemented as follows:
from domain.ports.repositories import ISalesmanRepository
from fastapi import HTTPException, status
from fastapi_jwt_auth import AuthJWT
from fastapi_jwt_auth.exceptions import JWTDecodeError
from shared.exceptions import EntityNotFound
from adapters.api.authentication.config import User
class AuthenticateService:
def __init__(self, user_repo: ISalesmanRepository):
self._repo = user_repo
def __call__(self, auth: AuthJWT) -> User:
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
auth.jwt_required()
user_id = auth.get_jwt_subject()
except JWTDecodeError:
raise credentials_exception
try:
user = self._repo.get_by_id(user_id)
return user
except EntityNotFound:
raise credentials_exception
So the behavior is basically:
Is jwt is valid, get user from repository and returns
Raise 401 if jwt is invalid
The problem is that in every controller implemented I have to repeat the process. I tried to implement a decorator that injects the user into the controller in case of success but I couldn't. I'm sure that the best way to implement this is to use fastAPI's Depends dependency injector.
Today, a controller looks something like this:
from typing import Optional
from adapters.api.services import authenticate_service, create_sale_service
from fastapi import APIRouter, Depends
from fastapi_jwt_auth import AuthJWT
from pydantic import BaseModel
router = APIRouter()
class Request(BaseModel):
code: str
value: float
date: str
status: Optional[str] = None
#router.post('/sale')
def create_sale(request: Request, auth: AuthJWT = Depends()):
user = authenticate_service(auth)
result = create_sale_service.handle(
{"salesman": user, "sale": request.dict()}
)
return result.dict()
How can I abstract my authentication so that my controllers look like any of the versions below:
# Option 1: decorator
#router.post('/sale')
#authentication_required
def create_sale(request: Request, user: User): # User is the `__call__` response from `AuthenticateService` class
result = create_sale_service.handle(
{"salesman": user, "sale": request.dict()}
)
return result.dict()
# Option 2:
#router.post('/sale')
def create_sale(request: Request, user: User = Depends(authenticate_service)): # Something like that, using the depends to inject User to me
result = create_sale_service.handle(
{"salesman": user, "sale": request.dict()}
)
return result.dict()
So I read a little more the Depends documentation and realize whats was going wrong with my attempt to inject the user on controller signature.
Right way to implement:
> AuthService class
class AuthenticateService:
def __init__(self, user_repo: ISalesmanRepository):
self._repo = user_repo
def __call__(self, auth: AuthJWT = Depends()) -> User:
...
authenticate_service = AuthenticateService(user_repository)
> Controller
#router.post('/sale')
def create_sale(request: Request, user: User = Depends(authenticate_service)):
result = create_sale_service.handle(
{"salesman": user, "sale": request.dict()}
)
return result.dict()
The python docs https://docs.python.org/3/library/exceptions.html#built-in-exceptions
and this SO question mention the __cause__ and __context__ attributes on an exception object.
Python 3.x (beazley): __context__ vs __cause__ attributes in exception handling
However, when using a debugger to inspect an exception object (with the debuggers set to work on a raise) the exception object doesn't appear to have these attributes and just appears as a tuple.
(eg from my debugger - pycharm) https://imgur.com/a/63oW1fV
This occured with the debugger started based on the raise on the last line.
try:
response = requests.request(method, url, json=payload, headers=HEADERS)
except (requests.ConnectionError, requests.Timeout) as e:
logger.exception("Api unavailable")
raise errors.Unavailable('Api unavailable') from e
try:
response.raise_for_status()
except requests.exceptions.HTTPError as e:
logger.exception("Api HTTP error")
try:
raw_data = response.json()
except json.JSONDecodeError as e:
raise errors.ApiHTTPError(f'{response.status_code}, {response.text}',
text=response.text) from e
api_errors = raw_data.get('errors')
message = raw_data.get('message')
raise errors.ApiHTTPError(f'HTTP Error {response.status_code}, {message}, {api_errors}', text=response.text,
api_errors=api_errors) from e
errors.py
class SwitcherError(Exception):
pass
class Unavailable(SwitcherError):
pass
class ApiHTTPError(SwitcherError):
def __init__(self, message=None, text=None, api_errors=None):
self.text = text
self.message = message
self.errors = api_errors
def __str__(self):
return self.message
class ApiJsonError(SwitcherError):
def __init__(self, message=None, text=None):
self.text = text
self.message = message
def __str__(self):
return self.message
class ApiError(SwitcherError):
def __init__(self, message, status_code, data, status=None,):
self.message = message
self.status_code = status_code
self.data = data
self.status = status
def __str__(self):
return self.message
That __exception__ thing isn't an exception. It looks like PyCharm has taken sys.exc_info() and stuffed it into an __exception__ variable. The exception is the second tuple element, and that's where you should be looking for __cause__ and __context__.
This is a module from PubNub that I'm using to publish a message to a topic from an API. By design I've kept the PubNub object singleton.
class Pubnub:
instance = None
#classmethod
def get(cls):
if cls.instance is None:
cls.instance = cls()
return cls.instance
def __init__(self):
with open('config/config.yaml', 'r') as stream:
try:
conf = yaml.load(stream)
pnconfig = PNConfiguration()
pnconfig.subscribe_key = conf['pubnub']['publish_key']
pnconfig.publish_key = conf['pubnub']['subscribe_key']
pnconfig.ssl = False
self.pubnub = PubNub(pnconfig)
except yaml.YAMLError as e:
logger.error(str(e))
def publish(self, channel):
try:
envelope = self.pubnub.publish().channel(channel).message({
'message': True
}).sync()
print("publish timetoken: %d" % envelope.result.timetoken)
except PubNubException as e:
logger.error(str(e))
This is how I'm calling it,
class SendCommunityTextMessage(views.APIView):
def post(self, request, **kwargs):
try:
client_id = request.GET['client_id']
client_secret = request.GET['client_secret']
if Authenticator.authenticate_client(client_id, client_secret):
try:
//do something
try:
//do something more
pubbub = Pubnub.get()
pubbub.publish(receiver.hex_code)
return Response({"Success": CommunityTextMessageSerializer(message).data},
status=status.HTTP_200_OK)
except KeyError as e:
return Response({"Failure": str(e)}, status=status.HTTP_400_BAD_REQUEST)
except (User.DoesNotExist, CommunityRoom.DoesNotExist) as e:
return Response({"Failure": str(e)}, status=status.HTTP_404_NOT_FOUND)
else:
return Response({"Failure": "Invalid client"}, status=status.HTTP_403_FORBIDDEN)
except KeyError as _:
return Response({"Failure": "Probably a typo, read the docs to use this API."},
status=status.HTTP_400_BAD_REQUEST)
The issue is this slows down the API by minutes. How can I call the two lines,
pubbub = Pubnub.get()
pubbub.publish(receiver.hex_code)
asynchronously and return out of the view without waiting for the call to finish.
Thanks in anticipation.