I have a chalice project (1.26.2) which is always exiting with a time out when deployed, chalice local works fine.
This is my project structure:
This is the code in my app.py:
from datetime import datetime
from decimal import Decimal
import boto3
import firebase_admin
from chalice import Chalice, AuthResponse
from chalice.app import AuthRequest
from firebase_admin import credentials, auth
from chalicelib import crud
from chalicelib import models
from chalicelib import schemas
from chalicelib.auth import full_user_from_context, user_from_context
from chalicelib.db import SessionLocal, engine
app = Chalice(app_name='server-aws')
BUCKET = 'meet-app'
s3_client = boto3.client('s3')
cred = credentials.Certificate('chalicelib/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
models.Base.metadata.create_all(bind=engine)
DISTANCE_IN_METERS = 100
_DB = None
def get_db():
global _DB
if _DB is None:
_DB = SessionLocal()
return _DB
#app.lambda_function(name='test-function')
def create_user(event, context):
return {'hello': 'world'}
#app.route('/health')
def health():
return {'status': 'ok'}
#app.authorizer()
def token_authorizer(auth_request: AuthRequest) -> AuthResponse:
token = auth_request.token
try:
decoded_token = auth.verify_id_token(token)
decoded = decoded_token
allowed_routes = [
'/auth',
'/me',
]
if 'permission_verified' in decoded and decoded['permission_verified'] is True:
allowed_routes.append('/me/location')
allowed_routes.append('/nearby')
allowed_routes.append('/me/profile-image')
print('routes', allowed_routes)
return AuthResponse(routes=allowed_routes, principal_id=decoded['sub'], context=decoded)
except Exception as e:
print('error', e)
return AuthResponse(routes=[], principal_id='non-user')
#app.route('/auth', methods=['GET'], authorizer=token_authorizer)
def authorize():
u = user_from_context(app.current_request.context)
user = crud.get_user(get_db(), u['uid'])
if user is None:
user = crud.create_user(get_db(), schemas.UserCreate(
uid=u['uid'],
phone=u['phone_number'],
permission_verified=True # TODO: find verification method
))
token = auth.create_custom_token(user.uid, {
"permission_verified": user.permission_verified,
"uid": user.uid,
"phone": user.phone,
"name": user.name,
"linkedin": user.linkedin,
"instagram": user.instagram,
})
return {
'user': user.__json__(),
'token': token.decode()
}
#app.route('/me', methods=["PUT"], authorizer=token_authorizer)
def update_me():
r = app.current_request
u = full_user_from_context(r.context)
data = r.json_body
u = crud.update_user(get_db(), schemas.UserUpdate(
uid=u.uid,
name=data.get('name'),
phone=data.get('phone'),
instagram=data.get('instagram'),
linkedin=data.get('linkedin'),
))
if u is None: # todo: code
return {
"error": "could not update"
}
return {
"user": u.__json__()
}
#app.route('/me/profile-image', methods=["PUT"], content_types=['application/octet-stream'],
authorizer=token_authorizer)
def update_me():
r = app.current_request
u = full_user_from_context(r.context)
data = r.raw_body
file_name = u.uid
tmp_file_name = '/tmp/' + file_name + '.jpg'
with open(tmp_file_name, 'wb') as tmp_file:
tmp_file.write(data)
key = 'profile-images/' + file_name
try:
s3_client.upload_file(tmp_file_name, BUCKET, key, ExtraArgs={'ACL': 'public-read'})
except Exception as e:
app.log.error(e)
return {
"error": str(e)
}
url = f'https://{BUCKET}.s3.amazonaws.com/{key}'
u = crud.update_user(get_db(), schemas.UserUpdate(
uid=u.uid,
profile_image_url=url
))
return {
"url": url
}
#app.route('/me/location', methods=["PUT"], authorizer=token_authorizer)
def update_me_location():
r = app.current_request
u = full_user_from_context(r.context)
data = r.json_body
lat = Decimal(str(data.get('latitude')))
lng = Decimal(str(data.get('longitude')))
loc = crud.update_user_location(get_db(), schemas.UserLocationUpdate(
uid=u.uid,
latitude=lat,
longitude=lng,
timestamp=datetime.now(),
geo=f'POINT({lng} {lat})'
))
if loc is None:
loc = crud.create_user_location(get_db(), schemas.UserLocationCreate(
uid=u.uid,
latitude=lat,
longitude=lng
))
loc = schemas.UserLocationGet(
uid=u.uid,
user=schemas.UserGet(
uid=u.uid,
name=u.name,
linkedin=u.linkedin,
instagram=u.instagram,
profile_image_url=u.profile_image_url
),
latitude=loc.latitude,
longitude=loc.longitude,
timestamp=loc.timestamp.isoformat()
)
return {
'loc': loc.json()
}
#app.route('/nearby', methods=["GET"], authorizer=token_authorizer)
def nearby():
r = app.current_request
u = full_user_from_context(r.context)
user_location = crud.get_user_location(get_db(), u.uid)
if user_location is None:
return {
"error": "no user location"
} # todo: better errro
nearby_users = crud.get_nearby_users(get_db(), u.uid, schemas.UserLocationGet(
uid=user_location.user_id,
latitude=user_location.latitude,
longitude=user_location.longitude,
user=u,
timestamp=user_location.timestamp.isoformat()
), DISTANCE_IN_METERS)
return {
"nearby_distance_in_meters": DISTANCE_IN_METERS,
"nearby_users": list(map(lambda x: schemas.UserLocationGet(
uid=x.user_id,
latitude=x.latitude,
longitude=x.longitude,
timestamp=x.timestamp.isoformat(),
user=schemas.UserGet(
uid=x.user.uid,
name=x.user.name,
instagram=x.user.instagram,
linkedin=x.user.linkedin,
profile_image_url=x.user.profile_image_url
)
).dict(), nearby_users))
}
This is the response when I invoke the test-function from the AWS console:
This is what I get when I do chalice logs:
Traceback (most recent call last):[ERROR] Runtime.ImportModuleError: Unable to import module 'app': No module named 'crud'
Traceback (most recent call last):[ERROR] Runtime.ImportModuleError: Unable to import module 'app': No module named 'crud'
2021-11-14 19:29:04.197000 88eb68 2021-11-14T19:29:04.197Z c143dcd4-e212-41f1-a786-7d86e4b58e59 Task timed out after 60.06 seconds
This is my requirements.txt:
chalice~=1.26.2
firebase-admin
boto3~=1.18.53
botocore
sqlalchemy
pydantic
# psycopg2
GeoAlchemy2
psycopg2-binary
I need to use psycopg2 so maybe that's the problem.
Every http request results in a 504 time out.
In local mode everything works fine.
Thanks in advance.
your chalicelib package folder's __init__.py (it must be written like this) has an extra underscore at the end of it. So python import system doesn't recognize such folder as a package, hence the error.
Related
i am trying to make a function that uses multiple aws services in a lambda function :
import os
import boto3
import hmac, hashlib, base64, copy
def lambda_handler(event, context):
secretsmanager = boto3.client('secretsmanager')
secret_response = secretsmanager.get_secret_value(SecretId = os.environ.get('cognitoSecretID'))
cognito = boto3.client('cognito-idp')
cognito_pool_id = os.environ.get('cognitoPoolID')
event_body = event['body']
username = event_body['email']
secret = secret_response['SecretString']
raw_message = username + cognito_pool_id
message = bytes(raw_message, 'utf-8')
secret = bytes(secret,'utf-8')
secret_hash = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest()).decode()
authParameters = {
'USERNAME': username,
'PASSWORD': event_body['password'],
'SECRET_HASH': secret_hash
}
cognito.admin_initiate_auth(UserPoolId = cognito_pool_id, ClientId = os.environ.get('cognitoClientID'), AuthFlow = "ADMIN_USER_PASSWORD_AUTH", AuthParameters = authParameters )
return True
i am testing git with pytest as follows :
import os
import pytest
from unittest.mock import call
import boto3
import hmac, hashlib, base64
from src.DacAdminsLogin import lambda_handler
from __mocks__.SecretsManagerMock import SecretsManagerMock
MockLambdaHandlerEvent = {
'body' : {
'email': "abdelouahedelhariri#gmail.com",
'password': "test"
}
}
#pytest.fixture
def dummy_secret(monkeypatch):
dummySecret = 'adummytest'
monkeypatch.setenv('cognitoSecretID', dummySecret, prepend=False)
return dummySecret
#pytest.fixture
def dummy_cognito_id(monkeypatch):
dummyCognitoID = 'adummycognitoid'
monkeypatch.setenv('cognitoClientID', dummyCognitoID, prepend=False)
return 'adummycognitoid'
#pytest.fixture
def dummy_cognito_pool_id(monkeypatch):
dummyCognitoPoolID = 'adummycognitopoolid'
monkeypatch.setenv('cognitoPoolID', dummyCognitoPoolID, prepend=False)
return 'adummycognitopoolid'
#pytest.fixture
def secret_manager(mocker, dummy_secret):
mock = mocker.patch('__mocks__.SecretsManagerMock.SecretsManagerMock')
mock.get_secret_value.return_value = {'SecretString' : dummy_secret}
return mock
#pytest.fixture
def cognito(mocker):
return mocker.patch('__mocks__.CognitoMock.CognitoMock', return_value= "Test secret")
#pytest.fixture
def client(mocker, secret_manager, cognito):
return mocker.patch('boto3.client', side_effect= [secret_manager, cognito])
def test_create_secrets_manager_client(client):
lambda_handler(MockLambdaHandlerEvent,1)
client.assert_has_calls([call('secretsmanager')])
def test_get_secret_value_call(client ,secret_manager, dummy_secret):
lambda_handler(MockLambdaHandlerEvent,1)
secret_manager.get_secret_value.assert_called_once_with(SecretId= dummy_secret)
def test_create_cognito_client(client ,secret_manager, dummy_secret):
lambda_handler(MockLambdaHandlerEvent,1)
client.assert_has_calls([call('secretsmanager'), call('cognito')])
def test_admin_initiate_auth_call(client, monkeypatch , cognito, dummy_secret, dummy_cognito_id, dummy_cognito_pool_id):
MockLambdaHandlerEventBody = MockLambdaHandlerEvent['body']
username = MockLambdaHandlerEventBody['email']
app_client_id = dummy_cognito_pool_id
key = dummy_secret
message = bytes(username+app_client_id,'utf-8')
key = bytes(dummy_secret,'utf-8')
secret_hash = base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()
authParameters = {
'USERNAME': username,
'PASSWORD': MockLambdaHandlerEventBody['password'],
'SECRET_HASH': secret_hash
}
lambda_handler(MockLambdaHandlerEvent,1)
cognito.admin_initiate_auth.assert_called_once_with(UserPoolId = dummy_cognito_pool_id, ClientId = dummy_cognito_id, AuthFlow = "ADMIN_USER_PASSWORD_AUTH", AuthParameters = authParameters )
I am new to python and i don't know why i keep getting the following error : TypeError: can only concatenate str (not "NoneType") to str, coming from the raw_message concatenation.
When i comment out the cognito.admin_initiate_auth.assert_called_once_with(UserPoolId = dummy_cognito_pool_id, ClientId = dummy_cognito_id, AuthFlow = "ADMIN_USER_PASSWORD_AUTH", AuthParameters = authParameters )
or change for example the UserPoolId to another value the error disappears.
When I am trying to run my python code in lambda passing the handler to the function.module getting the below error, any suggestions how i could resolve this?
the below file test_client_visitor is triggered to call the client_visitor and send an email to the clients accordingly, when i run thd python file test_client_visitor in my local i get the email triggered successfully but in lambda facing the issue.
file_name: test_client_visitor
function = __import__('client_visitor')
handler = function.scan_clients
class TestFunction(unittest.TestCase):
def test_function(self):
file = open('event.json', 'rb')
try:
ba = bytearray(file.read())
event = jsonpickle.decode(ba)
print('## EVENT')
print(jsonpickle.encode(event))
context = {'requestid': '1234'}
result = handler(event, context)
print(result)
self.assertTrue(result, 'Emails could not be sent!')
finally:
file.close()
file.close()
if __name__ == '__main__':
unittest.main()
file_name: client_visitor.py
import datetime
import boto3
from aws_ses import send_bulk_templated_email
# boto3.set_stream_logger('botocore', level='DEBUG')
from mongodb import get_mongo_db
def process_clients(clients, developers, clients_to_be_notified, days):
if not clients:
pass
check_date = datetime.datetime.now() + datetime.timedelta(days)
for client in clients:
client_id_ = client['client_id']
if 'developer_id' in client:
developers[client_id_] = client['developer_id']
else:
if 'secrets' in client:
secrets = client['secrets']
for secret in secrets:
if 'not_on_or_after' in secret and secret['not_on_or_after'] < check_date.timestamp():
clients_to_be_notified.append({'client_id': client_id_,
'expiration_date': datetime.datetime.fromtimestamp(
secret['not_on_or_after']).strftime('%m/%d/%Y')})
print("adding client to notify List", client_id_, ":", client['sort'])
def notify_clients(clients_to_be_notified, developers):
developer_id_list = []
for client_secret in clients_to_be_notified:
developer_id_list.append(developers[client_secret['client_id']])
if developer_id_list:
db = get_mongo_db()
if db:
users = list(db.users.find({'guid': {'$in': developer_id_list}}, {'email', 'guid'}))
need_to_send_email = False
for user in users:
for client_secret in clients_to_be_notified:
if developers[client_secret['client_id']] == user['guid']:
client_secret['email'] = user['email']
need_to_send_email = True
break
if need_to_send_email:
return send_bulk_templated_email(clients_to_be_notified)
else:
return False
return True
def scan_clients(event, context):
local = False
if 'local' in event:
local = event['local'] == 'True'
if local:
dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")
else:
dynamodb = boto3.resource('dynamodb')
days = 30
if 'days' in event:
days = int(event['days'])
print(f"Scanning Clients with {days} or less to secret expiration")
table = dynamodb.Table('****')
scan_kwargs = {
'ProjectionExpression': 'client_id, sort, developer_id, secrets, approved'
}
test = False
if 'test' in event:
test = event['test'] == 'True'
done = False
start_key = None
developers = {}
clients_to_be_notified = []
if test:
developers['idm-portal1'] = '***'
clients_to_be_notified = [{'client_id': 'idm-portal1', 'expiration_date': '04/17/2021'}]
while not done:
if start_key:
scan_kwargs['ExclusiveStartKey'] = start_key
response = table.scan(**scan_kwargs)
process_clients(response.get('Items', []), developers, clients_to_be_notified, days)
start_key = response.get('LastEvaluatedKey', None)
done = start_key is None
print("total developers ", len(developers), " total clients_to_be_notified ", len(clients_to_be_notified))
return notify_clients(clients_to_be_notified, developers)
if __name__ == '__main__':
scan_clients(event={'days': 30, 'local': False, 'test': True}, context=None)
Response
{
"errorMessage": "Unable to import module 'test_client_visitor': No module named 'test_client_visitor'",
"errorType": "Runtime.ImportModuleError",
"stackTrace": []
}
Your file must be named test_client_visitor.py. The way lambda runs the code is by trying to import the main file and call the handler function. See the AWS docs to set up a handler for Python.
The reason you didn't run into this issue locally is because I assume you are calling python directly on the command line — python test_client_visitor. When you import a module in Python, the file has to end in the .py extension.
Able to fix this issue with right packaging of the contents to zip, avoided the creation of extra folder with the below command.
Command:
cd folder; zip -r ../filename.zip *
Thankyou everyone for your inputs.
I am trying to deploy my XGboost model into kubernetes. I am facing a problem in writing the flask code. Here is the code(imported from github). Whenever I try to deploy into web server, I am facing the error message: invalid parameters. Please help me to solve this issue and thank you in advance.
'''
#
import json
import pickle
import numpy as np
from flask import Flask, request
#
flask_app = Flask(__name__)
#ML model path
model_path = "Y:/Docker_Tests/Deploy-ML-model-master/Deploy-ML-model-master/ML_Model/model2.pkl"
#flask_app.route('/', methods=['GET'])
def index_page():
return_data = {
"error" : "0",
"message" : "Successful"
}
return flask_app.response_class(response=json.dumps(return_data), mimetype='application/json')
#flask_app.route('/predict',methods=['GET'])
def model_deploy():
try:
age = request.form.get('age')
bs_fast = request.form.get('BS_Fast')
bs_pp = request.form.get('BS_pp')
plasma_r = request.form.get('Plasma_R')
plasma_f = request.form.get('Plasma_F')
HbA1c = request.form.get('HbA1c')
fields = [age,bs_fast,bs_pp,plasma_r,plasma_f,HbA1c]
if not None in fields:
#Datapreprocessing Convert the values to float
age = float(age)
bs_fast = float(bs_fast)
bs_pp = float(bs_pp)
plasma_r = float(plasma_r)
plasma_f = float(plasma_f)
hbA1c = float(HbA1c)
result = [age,bs_fast,bs_pp,plasma_r,plasma_f,HbA1c]
#Passing data to model & loading the model from disk
classifier = pickle.load(open(model_path, 'rb'))
prediction = classifier.predict([result])[0]
conf_score = np.max(classifier.predict_proba([result]))*100
return_data = {
"error" : '0',
"message" : 'Successfull',
"prediction": prediction,
"confidence_score" : conf_score.round(2)
}
else:
return_data = {
"error" : '1',
"message": "Invalid Parameters"
}
except Exception as e:
return_data = {
'error' : '2',
"message": str(e)
}
return flask_app.response_class(response=json.dumps(return_data), mimetype='application/json')
if __name__ == "__main__":
flask_app.run(host ='0.0.0.0',port=9091, debug=True)
'''
I have some troubles with this application. What I need is that If I detect a change in the database (FIREBASE) particularly in 'sala' and 'ventilacion' nodes the function do what it have to do. If there isn't any change in the database it would not do nothing. I am using python and pyrebase library. Here is the code. Thank you very much for you help.
import pyrebase
import serial
import time
config = {
#firebase configurations
}
firebase = pyrebase.initialize_app(config)
db = firebase.database()
def ReconfiguracionFabrica():
ser.write('AT')
time.sleep(0.2)
ser.write('AT+RENEW')
time.sleep(0.3)
def ConfiguracionMaster():
time.sleep(0.5)
ser.write('AT+IMME1')
time.sleep(0.350)
ser.write('AT+ROLE1')
time.sleep(0.2)
ser = serial.Serial(port="/dev/ttyAMA0", baudrate=9600, timeout=1)
ReconfiguracionFabrica()
time.sleep(0.1)
ConfiguracionMaster()
time.sleep(0.1)
print "********** INICIO *************"
ser.flushInput()
contador = 0
prender = ''
ventilacion1 = ''
checkeo = ''
while True:
#if db.child("sala").: # It is the line where would be the conditional that allows me to detect any change only in the sala's node.
salidaLed1 = db.child("sala").get()
ser.write('AT')
time.sleep(0.1)
ser.write('AT+CON508CB16A7014')
time.sleep(0.1)
if salidaLed1.val() == True:
prender = ";"
if salidaLed1.val() == False:
prender = ","
ser.write('luz: %s \n' %(prender))
print ('luz: %s \n' %(prender))
time.sleep(1)
ser.read(checkeo)
if checkeo == 'j':
ReconfiguracionFabrica()
time.sleep(0.1)
ConfiguracionMaster()
Question: How to detect changes in firebase child
Note: All Examples use Public Access
Setup Example Data and verify it's readable.
This hase to be done once!
temperature_c = 30
data = {'date':time.strftime('%Y-%m-%d'),
'time':time.strftime('%H:%M:%S'),
'temperature':temperature_c}
db.child('public').child('Device_1').set(data)
response = db.child('public').child('Device_1').get()
print(response.val())
Create First Script doing Updates:
for t in [25, 26, 27, 28, 29, 30, 31, 32, 33, 35]:
temperature_c = t
data = {'date':time.strftime('%Y-%m-%d'),
'time':time.strftime('%H:%M:%S'),
'temperature':temperature_c}
db.child('public').child('Device_1').update(data)
time.sleep(60)
Create Second Script with Stream Handler
def stream_handler(message):
print('event={m[event]}; path={m[path]}; data={m[data]}'
.format(m=message))
my_stream =db.child('public').child('Device_1').stream(stream_handler)
# Run Stream Handler forever
while True:
data = input("[{}] Type exit to disconnect: ".format('?'))
if data.strip().lower() == 'exit':
print('Stop Stream Handler')
if my_stream: my_stream.close()
break
Run Stream Handler Script:
Response Output from def stream_handler after startup (Initial Data):
event="put"; path=/; data={'Device_1': {'temperature': 30, 'time': '13:34:24', 'date': '2017-07-20'}}
Run Updater Script:
Watch Output from Stream Handler Script
Response Output from def stream_handler after First Update Data:
event=patch; path=/Device_1; data={'temperature': 25, 'time': '13:49:12'}
Tested with Python: 3.4.2
Pyrebase
streaming
You can listen to live changes to your data with the stream() method.
def stream_handler(message):
print(message["event"]) # put
print(message["path"]) # /-K7yGTTEp7O549EzTYtI
print(message["data"]) # {'title': 'Pyrebase', "body": "etc..."}
my_stream = db.child("posts").stream(stream_handler)
You should at least handle put and patch events. Refer to "Streaming from the REST API" for details.
I know this post is 2 years old but hope this helps. Try using firebase_admin module.
Use this command - pip install firebase-admin
I too had a requirement where I needed to check for changes made to the Firebase database. I referred here
Following is a sample code based on your question which you can refer from and try it out.
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://example.firebaseio.com',
'databaseAuthVariableOverride': None
})
def ignore_first_call(fn):
called = False
def wrapper(*args, **kwargs):
nonlocal called
if called:
return fn(*args, **kwargs)
else:
called = True
return None
return wrapper
#ignore_first_call
def listener(event):
print(event.event_type) # can be 'put' or 'patch'
print(event.path) # relative to the reference, it seems
print(event.data) # new data at /reference/event.path. None if deleted
node = str(event.path).split('/')[-2] #you can slice the path according to your requirement
property = str(event.path).split('/')[-1]
value = event.data
if (node=='sala'):
#do something
elif (node=='ventilacion'):
#do something
else:
#do something else
db.reference('/').listen(listener)
I was working on the same thing so according to current updates on pyrebase and learning from above posted answers, I got this running perfectly.(Please make sure your python is upgraded from python2 to python3 for running pyrebase and firebase-admin)
import firebase_admin
import pyrebase
from firebase_admin import credentials
config = {
"apiKey": "",
"authDomain": "",
"databaseURL": "",
"projectId": "",
"storageBucket": "",
"serviceAccount": "path to the service account json file you downloaded",
"messagingSenderId": "",
"appId": "",
"measurementId": ""
}
firebase = pyrebase.initialize_app(config)
storage = firebase.storage()
cred = credentials.Certificate("path to downloaded json file")
firebase_admin.initialize_app(cred, {
"databaseURL": "same as config",
"databaseAuthVariableOverride": None
})
db = firebase.database()
def ignore_first_call(fn):
called = False
def wrapper(*args, **kwargs):
nonlocal called
if called:
return fn(*args, **kwargs)
else:
called = True
return None
return wrapper
def stream_handler(message):
ab = str(1)
all_videos = storage.child("videos/").list_files() #node where files are
path_on_local = "local path to save the downloads"
print(message["event"]) # put
print(message["path"]) # /-K7yGTTEp7O549EzTYtI
print(message["data"]) # {'title': 'Pyrebase', "body": "etc..."}
node = str(message["path"]).split('/')[-2]
property = str(message["path"]).split('/')[-1]
value = message["data"]
if (message["event"] == "put"):
for videos in all_videos:
try:
print(videos.name)
z = storage.child(videos.name).get_url(None)
storage.child(videos.name).download(path_on_local + "/" + ab + ".mp4")
x = int(ab)
ab = str(x + 1)
except:
print('Download Failed')
else:
print("error")
my_stream = db.child("videos").stream(stream_handler)
This is my code for testing Trello API:
import string
import random
import requests
from settings import *
nonce = lambda x: ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10 if not x else x))
def get_board_detals(board_id):
url = "https://trello.com/1/boards/" + board_id
params = {"key":key,
"token":token}
return requests.get(url=url, params=params)
def post_board_name(board_name):
url = "https://api.trello.com/1/boards"
params = {"key": key,
"token": token,
"name": board_name}
return requests.post(url=url, params=params)
def put_new_board_name(board_id):
url = "https://api.trello.com/1/boards" + board_id
params = {"key": key,
"token": token}
return requests.put(url=url, params=params)
and code for unittest:
import unittest
from board_details import *
class BoardDetails(unittest.TestCase):
def setUp(self):
self.name = nonce(10)
def test_put_new_name(self):
result_post = post_board_name(self.name)
board_id = result_post.json()['id']
result_put = put_new_board_name(board_id)
self.assertEqual(result_put.status_code, 200)
self.assertIn(result_put.json()['name'], self.name)
if __name__ == '__main__':
unittest.main()
When I run the code, I receive an error: AssertionError: 404 != 200.
I don't know why it is like that, can someone point out what's the reason for my error?
I did it like this and it seems to work fine:
function:
def put_new_board_name(board_id, board_name):
url = "https://api.trello.com/1/boards/" + board_id +"/name"
params = {"key": key,
"token": token,
"value" : board_name}
return requests.put(url=url, params=params)
and method:
def test_put_new_name(self):
result_post = post_board_name(self.name)
board_id = result_post.json()['id']
result_put = put_new_board_name(board_id, board_name=self.name)
self.assertEqual(result_put.status_code, 200)
self.assertIn(result_put.json()['name'], self.name)