I am facing an error while running the test case using json data in python - pytest

Here i am trying to write a pytest for my json data. But while i am running the test case i am facing an error. So i have mention the error below please let me know where I am going wrong. So that i can correct it. I am trying to load a json data and for that i have written a test cases using pytest. My goal is to write a test case for crud operations using json data
"
import json
import os
from pathlib import Path
import pytest
import requests
def get_test_data(filename):
folder_path = os.path.abspath(Path(os.path.dirname(__file__)))
folder = os.path.join(folder_path, 'TestData')
jsonfile = os.path.join(folder, filename)
with open(jsonfile) as file:
data = json.load(file)
return data
def test_valid_ok(database_api):
data = get_test_data('test_data.json')
response = database_api.get_user_info(data)
assert requests.codes['ok'] == response.status_code
"
*This is my json file*
"
{
"valid_data": [
{
"id": "1234",
"name": "John"
},
{
"id": "2234",
"name": "Mary"
},
{
"id": "3234",
"name": "Kenny"
}
],
"invalid_data": [
{
"id": "1234",
"name": "Mary"
},
{
"id": "2234",
"name": "Kenny"
},
{
"id": "3234",
"name": "John"
}
]
}
"
*Error i am facing*
"
E fixture 'database_api' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
"

Related

Error #1487713 when trying to link video to campaign ad

I am having trouble creating a video ad on AdVideos platform. I am able to successfully create campaigns, ad sets, and ads, but am encountering an error #1487713 when uploading a specific 15-second MP4 video from Google Drive. Some other videos have uploaded successfully. What could be causing this issue and how can I resolve it?
When creating the video with the API/ using that id for the ad, i dont get any errors (i get a advideo ID back). only when i navigate to the business campaign manager it gives me the error "#1487713 check if your video is in the right format and try again"
here is the code im using to test, again some videos DO work (all around 10-20 seconds)
# creates advideo
params = {
"name": "TEST",
"file_url": drive_url_to_download(video_url),
"title": "TEST",
}
url = f"https://graph.facebook.com/v15.0/{act}/advideos?access_token={fb_token}"
rr = requests.post(url, params=params)
print(rr.json(), rr.status_code)
# exit()
# creates a campaign
campaign_params = {
"name": "TEST",
"objective": "REACH",
"status": "PAUSED",
"special_ad_categories": ["NONE"],
}
url = f"https://graph.facebook.com/v15.0/{act}/campaigns?access_token={fb_token}"
r = requests.post(url, params=campaign_params)
print(r.json())
adset_params = {
"name": "TEST",
"campaign_id": r.json()["id"],
"billing_event": "IMPRESSIONS",
"optimization_goal": "REACH",
"bid_amount": "100",
"daily_budget": "1000",
"targeting": str({
"geo_locations": {
"custom_locations": [
{
"address_string": "someaddr",
"radius": "5",
"distance_unit": "kilometer"
},
]
},
"facebook_positions": ["feed", "video_feeds", "instant_article", "marketplace", "video_feeds", "story", "search"],
}),
"status": "PAUSED",
}
url = f"https://graph.facebook.com/v15.0/{act}/adsets?access_token={fb_token}"
r = requests.post(url, params=adset_params)
print(r.json())
# create ad with video
ad_params = {
"name": "TEST",
"adset_id": r.json()["id"],
"creative": str({
"name": "TEST333",
"object_story_spec": {
"page_id": "someid",
"video_data": {
"image_url": "someurl",
"call_to_action": {
"type": "NO_BUTTON",
},
"title": "TEST",
"message": "TEST",
"video_id": rr.json()["id"]
}
}
}),
"status": "PAUSED",
}
what is going on??

How to extract values from json string from api in scala?

I am trying to extract specific value from each json in a response from api.
for example if I have http response is kind of string array as below:
[
{
"trackerType": "WEB",
"id": 1,
"appId": "ap-website",
"host": {
"orgId": "ap",
"displayName": "AP Mart",
"id": "3",
"tenantId": "ap"
}
},
{
"trackerType": "WEB",
"id": 2,
"appId": "test-website",
"host": {
"orgId": "t1",
"tenantId": "trn11"
}
}
]
I wanted to extract or keep only list of values app_id and tenant_id as below:
[
{
"appId": "ap-website",
"tenantId": "ap"
},
{
"appId": "test-website",
"tenantId": "trn11"
}
]
If your HTTP response is quite big and you wouldn't hold it all in memory then consider using IO streams for parsing the body and serialization of the result list.
Below is an example of how it can be done with the dijon library.
Add dependency to your build file:
libraryDependencies += "me.vican.jorge" %% "dijon" % "0.5.0+18-46bbb74d", // Use %%% instead of %% for Scala.js
Import following packages:
import com.github.plokhotnyuk.jsoniter_scala.core._
import dijon._
import scala.language.dynamics._
Parse your input stream transforming it value by value in the callback to the output stream:
val in = new java.io.ByteArrayInputStream(
"""
[
{
"trackerType": "WEB",
"id": 1,
"appId": "ap-website",
"host": {
"orgId": "ap",
"displayName": "AP Mart",
"id": "3",
"tenantId": "ap"
}
},
{
"trackerType": "WEB",
"id": 2,
"appId": "test-website",
"host": {
"orgId": "t1",
"tenantId": "trn11"
}
}
]
""".getBytes("UTF-8"))
val out = new java.io.BufferedOutputStream(System.out)
out.write('[')
scanJsonArrayFromStream[SomeJson](in) {
var writeComma = false
x =>
if (writeComma) out.write(',') else writeComma = true
val json = obj("appId" -> x.appId, "tenantId" -> x.host.tenantId)
writeToStream[SomeJson](json, out)(codec)
true
} (codec)
out.write(']')
out.flush()
You can try it with Scastie here
When using this code in your application, you need to replace the source and destination of input and output streams.
There are other options how to solve your task. Please add more context that will help us in selection of the most simple and efficient solution.
Feel free to comment - I will be happy to help you in tuning the solution to your needs.

Cannot parametrize any value under placement.managedCluster.config

My goal is to create dataproc workflow template from python code. Meanwhile I want to have ability to parametrize placement.managedCluster.config.gceClusterConfig.subnetworkUri field during template instantiation.
I read template from json file like:
{
"id": "bigquery-extractor",
"placement": {
"managed_cluster": {
"config": {
"gce_cluster_config": {
"subnetwork_uri": "some-subnet-name"
},
"software_config" : {
"image_version": "1.5"
}
},
"cluster_name": "some-name"
}
},
"jobs": [
{
"pyspark_job": {
"args": [
"job_argument"
],
"main_python_file_uri": "gs:///path-to-file"
},
"step_id": "extract"
}
],
"parameters": [
{
"name": "CLUSTER_NAME",
"fields": [
"placement.managedCluster.clusterName"
]
},
{
"name": "SUBNETWORK_URI",
"fields": [
"placement.managedCluster.config.gceClusterConfig.subnetworkUri"
]
},
{
"name": "MAIN_PY_FILE",
"fields": [
"jobs['extract'].pysparkJob.mainPythonFileUri"
]
},
{
"name": "JOB_ARGUMENT",
"fields": [
"jobs['extract'].pysparkJob.args[0]"
]
}
]
}
code snippet I use:
options = ClientOptions(api_endpoint="{}-dataproc.googleapis.com:443".format(region))
client = dataproc.WorkflowTemplateServiceClient(client_options=options)
template_file = open(path_to_file, "r")
template_dict = eval(template_file.read())
print(template_dict)
template = dataproc.WorkflowTemplate(template_dict)
full_region_id = "projects/{project_id}/regions/{region}".format(project_id=project_id, region=region)
try:
client.create_workflow_template(
parent=full_region_id,
template=template
)
except AlreadyExists as err:
print(err)
pass
when I try to run this code I get the following error:
google.api_core.exceptions.InvalidArgument: 400 Invalid field path placement.managed_cluster.configuration.gce_cluster_config.subnetwork_uri: Field gce_cluster_config does not exist.
This behavior is the same also if I try to parametrize placement.managedCluster.config.softwareConfig.imageVersion, I will get
google.api_core.exceptions.InvalidArgument: 400 Invalid field path placement.managed_cluster.configuration.software_config.image_version: Field software_config does not exist.
But if I exclude any field under placement.managedCluster.config from parameters map, template is created successfully.
I didn't find any restriction on parametrizing these fields. Is there any? Or is it just me doing something wrong?
This doc listed the parameterizable fields. It seems that only managedCluster.name of managedCluster is parameterizable:
Managed cluster name. Dataproc will use the user-supplied name as the name prefix, and append random characters to create a unique cluster name. The cluster is deleted at the end of the workflow.
I don't see managedCluster.config parameterizable.

error on sending parameter values on event call

I have an intent which I am trying to invoke using event name, and trying to send parameters with it.
query_input = {
'event': {
"name": "greet",
"parameters": {
"mobile": "9876543210",
"plan": "pizza plan",
},
"language_code": "en"
}
}
response = session_client.detect_intent(session, query_input)
But I am getting error
ValueError: Protocol message Struct has no "mobile" field.
What am i doing wrong?
For now, I am sending parameters as below, its working fine:
from google.protobuf import struct_pb2
parameters = struct_pb2.Struct()
parameters["mobile"] = "9876543210"
parameters["plan"] = "pizza plan"
query_input = {
'event': {
"name": "greet",
"parameters": parameters,
"language_code": "en"
}
}
response = session_client.detect_intent(session, query_input)

Does Pymongo have validation rules built in?

I am trying to validate an inserted document against a schema, and was trying to find a way to validate the inserted document.
There are libraries like MongoEngine that say they do the work, but is there a way to do document validation directly via pymongo ?
The python driver docs are indeed a little light on how to use the db.command. Here is a complete working example:
from pymongo import MongoClient
from collections import OrderedDict
import sys
client = MongoClient() # supply connection args as appropriate
db = client.testX
db.myColl.drop()
db.create_collection("myColl") # Force create!
# $jsonSchema expression type is prefered. New since v3.6 (2017):
vexpr = {"$jsonSchema":
{
"bsonType": "object",
"required": [ "name", "year", "major", "gpa" ],
"properties": {
"name": {
"bsonType": "string",
"description": "must be a string and is required"
},
"gender": {
"bsonType": "string",
"description": "must be a string and is not required"
},
"year": {
"bsonType": "int",
"minimum": 2017,
"maximum": 3017,
"exclusiveMaximum": False,
"description": "must be an integer in [ 2017, 3017 ] and is required"
},
"major": {
"enum": [ "Math", "English", "Computer Science", "History", None ],
"description": "can only be one of the enum values and is required"
},
"gpa": {
# In case you might want to allow doubles OR int, then add
# "int" to the bsonType array below:
"bsonType": [ "double" ],
"minimum": 0,
"description": "must be a double and is required"
}
}
}
}
# Per the docs, args to command() require that the first kev/value pair
# be the command string and its principal argument, followed by other
# arguments. There are two ways to do this: Using an OrderDict:
cmd = OrderedDict([('collMod', 'myColl'),
('validator', vexpr),
('validationLevel', 'moderate')]
db.command(cmd)
# Or, use the kwargs construct:
# db.command('collMod','myColl', validator=vexpr, validationLevel='moderate')
try:
db.myColl.insert({"x":1})
print "NOT good; the insert above should have failed."
except:
print "OK. Expected exception:", sys.exc_info()
try:
okdoc = {"name":"buzz", "year":2019, "major":"Math", "gpa":3.8}
db.myColl.insert(okdoc)
print "All good."
except:
print "exc:", sys.exc_info()
MongoDB supports document validation at the engine level so you'll pick it up via pymongo. You declare your "schema" (rules actually) to the engine. Here's a great place to start: https://docs.mongodb.com/manual/core/document-validation/
You can make a separated JSON file for your Document Validations Schema, like this:
{
"collMod": "users",
"validator": {
"$jsonSchema": {
"bsonType": "object",
"required": ["email", "password","name"],
"properties": {
"email": {
"bsonType": "string",
"description": "Correo Electrónico"
},
"password": {
"bsonType": "string",
"description": "Una representación Hash de la contraseña"
},
"name": {
"bsonType": "object",
"required": ["first", "last"],
"description": "Objeto que separa los nombres y apellidos",
"properties": {
"first": {
"bsonType": "string",
"description": "Primer y segundo nombre"
},
"last": {
"bsonType": "string",
"description": "Primer y segundo apellido"
}
}
},
}
}
}
}
Then you can use in python script, example:
from pymongo import MongoClient
import json #parse JSON file as dict
from collections import OrderedDict #preserve the order (key, value) in the gived insertions on the dict
client = MongoClient("your_mongo_uri")
db = client.your_db_name
with open('your_schema_file.json', 'r') as j:
d = json.loads(j.read())
d = OrderedDict(d)
db.command(d)
OrderedDict Info
collMod Info
Schema Validation Info
I know 2 options to deal with:
By creating or setting schema for collection, so any insertions will be checked against it on server side, rejected or warned depending on validationAction
The following code demonstrates scheme creation and testing:
import pymongo
mongo_client = MongoClient(url=...,
port=...,
username=...,
password=...,
authSource=...,
authMechanism=...,
connect=True, )
mongo_client.server_info()
db = mongo_client.your_db
users = db.create_collection(name="users",
validator={"$jsonSchema": {
"bsonType": "object",
"required": ["username"],
"properties": {
"username": {
"bsonType": "string",
"pattern": "[a-z0-9]{5,15}",
"description": "user name (required), only lowercase letters "
"and digits allowed, from 5 to 15 characters long"
},
"email": {
"bsonType": "string",
"description": "User's email (optional)"
},
}
}},
validationAction="error",
)
# Inserting user document that fits the scheme
users.insert_one({"username": "admin", "email": "some_admin_mail"})
# Insertion below will be rejected with "pymongo.errors.WriteError: Document failed validation, full error"
# caused by too short username (root)
users.insert_one({"username": "root", "email": "some_root_mail"})
You can think about your Mongo's documents as ordinary JSON entities and check them on the client code side using standard JSON scheme validation
from jsonschema import validate
from jsonschema.exceptions import ValidationError
db = MongoClient(...).your_db
schema = {
"type": "object",
"required": ["username"],
"properties": {
"username": {"type": "string", "pattern": "[a-z0-9]{5,15}"},
"email": {"type": "string"},
},
}
try:
new_user = {"username": "admin", "email": "some_admin_mail"}
# No exception will be raised in validation below
validate(instance=new_user, schema=schema)
db.users.insert_one(new_user)
new_user = {"username": "root", "email": "some_root_mail"}
# Exception <ValidationError: 'root' does not match '[a-z0-9]{5,15}'> will be raised
validate(instance=new_user, schema=schema)
db.users.insert_one(new_user)
except ValidationError:
# Performing error