Django while running the server ModuleNotFoundError: No module named 'customer data' - python

I'm using django to make an API that connects to another one to get some data and update some values. The idea is that the api can be executed from a CLI through commands like upgrade customer_id target_subscription.
Before making the CLI file, the api works perfectly if you make requests to it (for example using vs code's thunder client). Once I make the CLI file and try to test I get the following error:
Im running the code on Windows 10 and WSL bash. I create the django project using:
django-admin startproject customer_data
cd customer_data
python manage.py startapp customer
My file/folder strucutre is this:
My API code:
class UpdateCustomerSubscriptionView(APIView):
def extractCustomerData(self, customer_id):
"""
Input: A customer id
Output: The customer data
"""
customer = None
try:
response = requests.get(f'{API_LINK}{customer_id}/')
customer_data = response.json()
customer = Customer(**customer_data)
except:
return Response({"error": "The ID does not exist or is badly formated."}, status=500)
return customer
def upgrade_or_downgrade(self, customer_id, target_subscription):
"""
Input: A customer id and a target subscription level
Output: The updated customer data
"""
# Validate that the id is not null
if customer_id is None:
return Response({"error": "The customer id is null."}, status=500)
# Validate that the new subscription is not null
if target_subscription is None:
return Response({"error": "The target subscriptiond is null."}, status=500)
# Validate that the new subscription is valid.
if target_subscription not in SUBSCRIPTION_CHOICES:
return Response({"error": "The target subscription level is not reachable."}, status=500)
# Get customer data from the external API
customer = self.extractCustomerData(customer_id)
if isinstance(customer, Response):
return customer
# Update the customer's subscription level
customer.data['SUBSCRIPTION'] = target_subscription
customer_data = model_to_dict(customer)
customer_data['id'] = customer.id
data_json = json.dumps(customer_data)
headers = {'content-type': 'application/json'}
# Making the PUT request to customerdataapi
r = requests.put(f'{API_LINK}{customer_id}/', data=data_json, headers=headers)
print(r.status_code)
return Response(customer_data, status=200)
def post(self, request):
# Get customer id and target subscription level from the request body
customer_id, target_subscription = sys.argv[1], sys.argv[2]
print(customer_id, target_subscription)
return self.upgrade_or_downgrade(customer_id, target_subscription)
My CLI file looks like this:
if [ "setup" == $1 ]; then
echo "Running setup"
# Replace this with any commands you need to setup your code
# pip install -r requirements.txt
exit;
fi
if [ "upgrade" == $1 ]; then
echo "Upgrading with args: ${#:2}"
# Use this line to call your code
export DJANGO_SETTINGS_MODULE="customer_data.settings"
python customer_data/customer/views.py upgrade ${#:2} || python3 customer_data/customer/views.py upgrade ${#:2}
exit;
fi
if [ "downgrade" == $1 ]; then
echo "Downgrading with args: ${#:2}"
# Use this line to call your code
export DJANGO_SETTINGS_MODULE="customer_data.settings"
python customer_data/customer/views.py downgrade ${#:2} || python3 customer_data/customer/views.py downgrade ${#:2}
exit;
fi
echo "Your first argument must be either 'setup', 'upgrade' or 'downgrade'"
exit 5;
I try this but doesnt work. In my setting.py file in INSTALLED_APPS I add 'customer' and 'rest_framework'. Thank you in advance for your help, any other information you need, please let me know.

Related

How to Run Python Script (Scrapy) From Ktor

What I'm trying to do:
Android Application (ADMIN) that gets job Title from user and fetches all the jobs related to it using Scrapy (Python) which are saved to database through API.
Android Application (CLIENT) that fetches all the data from database through API.
Problem:
I'm stuck on how to connect my python Script with Ktor.
Some Code for more clarity:
import spiders.Linkedin as linkedinSpider
linkedinSpider.main(numberOfPages=1, keywords="ios developer", location="US")
This piece of Code works fine and helps me to fetch and store data into database and returns True if saved successfully else False. I just need to call this function and all the work is done for me.
Similarly,
This is how i get data from the user through API from ADMIN Side using KTOR. Also this works fine.
// Fetchs New Jobs.
get("/fetch") {
val numberOfPages = call.request.queryParameters["pages"]?.toInt() ?: 1
val keyword = call.request.queryParameters["keyword"]
val location = call.request.queryParameters["location"]
if (numberOfPages < 1) {
call.respond(
status = HttpStatusCode.BadRequest,
message = Message(message = "Incorrect Page Number.")
)
} else {
call.respond(
status = HttpStatusCode.PK,
message = Message(message = "Process Completed.")
)
}
}
This is how i wanted the code to work logically.
// Fetch New Jobs.
get("/fetch") {
val numberOfPages = call.request.queryParameters["pages"]?.toInt() ?: 1
val keyword = call.request.queryParameters["keyword"]
val location = call.request.queryParameters["location"]
if (numberOfPages < 1) {
call.respond(
status = HttpStatusCode.BadRequest,
message = Message(message = "Incorrect Page Number.")
)
} else {
// TODO: Call Python Function Here and Check the Return Type. Something Like This.
if(linkedinSpider.main(numberOfPages=numberOfPages, keywords=keyword, location=location)) {
call.respond(
status = HttpStatusCode.OK,
message = Message(message = "Process Completed.")
)
} else {
call.respond(
status = HttpStatusCode.InternalServerError,
message = Message(message = "Something Went Wrong.")
)
}
}
}
Also these are two different individual projects. Do i need to merge them or something as when i tried it says no python interpreter found in intelliJ which i'm using as an IDE for Ktor Development. Also I tried to configure python interpreter but it seems of no use as it is not able to reference the variables or the python files.
Edit 1
This is what i tried
val processBuilder = ProcessBuilder(
"python3", "main.py"
)
val exitCode = processBuilder.start().waitFor()
if (exitCode == 0) {
println("Process Completed.")
} else {
println("Something Went Wrong.")
}
}
The exitCode i am getting is 2. But when i run the below code it works with exitCode 0.
ProcessBuilder("python3", "--version")
Edit 2
After This the code is working but not terminating and i get no output
This is the kotlin file i made to simulate the problem
package com.bhardwaj.routes
import java.io.File
fun main() {
val processBuilder = ProcessBuilder(
"python3", "main.py", "1", "android", "india"
)
processBuilder.directory(File("src/main/kotlin/com/bhardwaj/"))
val process = processBuilder.start()
val exitCode = process.waitFor()
if (exitCode == 0) {
val output = String(process.inputStream.readBytes())
print("Process Completed -> $output")
} else {
val output = String(process.errorStream.readBytes())
print("Something went wrong -> $output")
}
}
If i run same commands in terminal it works.
python3 src/main/kotlin/com/bhardwaj/main.py 1 "android" "india"
After i run same commands in the Terminal the output is ->
Edit 3
When I stopped default Scrapy logging, the code worked. It seems there is some limit to output stream in Process Builder. Here is what i did.
def __init__(self, number_of_pages=1, keywords="", location="", **kwargs):
super().__init__(**kwargs)
logging.getLogger('scrapy').setLevel(logging.WARNING)
This worked flawlessly in Development mode. But there is something more i want to discuss.
When I deployed the same on Heroku and made a get request that gives me 503 service unavailable after 30-40 sec later. But after another 20-30 sec i get my data into database. It's seems to be very confusing why this is happening.
For the flow of the program and clarity -
When i make get request to ktor, it request scrapy(A python program) to scrape data and store it in JSON file. After all the process done it make a request to another endpoint to store all the data to database and after all this it returns and respond the user with the particular status code it should give as output using call.respond in ktor.
Is the issue is due to another request made by the python program to the endpoint or it is related to heroku that we can handle one process at a time. Because there is no issue on development mode i.e. localhost url
When I stopped default Scrapy logging, the code worked. It seems there is some limit to output stream in Process Builder. Here is what i did.
def __init__(self, **kwargs):
super().__init__(**kwargs)
logging.getLogger('scrapy').setLevel(logging.WARNING)

How to solve customer_id error in google ads api(python)

Try running the example get_campaign.py in the google ads api.
The code was entered as follows
import argparse
import sys
from google.ads.google_ads.client import GoogleAdsClient
from google.ads.google_ads.errors import GoogleAdsException
def main(client, customer_id):
ga_service = client.get_service("GoogleAdsService", version="v6")
query = """
SELECT campaign.id, campaign.name
FROM campaign
ORDER BY campaign.id"""
# Issues a search request using streaming.
response = ga_service.search_stream(customer_id, query=query)
try:
for batch in response:
for row in batch.results:
print(
f"Campaign with ID {row.campaign.id} and name "
f'"{row.campaign.name}" was found.'
)
except GoogleAdsException as ex:
print(
f'Request with ID "{ex.request_id}" failed with status '
f'"{ex.error.code().name}" and includes the following errors:'
)
for error in ex.failure.errors:
print(f'\tError with message "{error.message}".')
if error.location:
for field_path_element in error.location.field_path_elements:
print(f"\t\tOn field: {field_path_element.field_name}")
sys.exit(1)
if __name__ == "__main__":
# GoogleAdsClient will read the google-ads.yaml configuration file in the
# home directory if none is specified.
google_ads_client = GoogleAdsClient.load_from_storage('C:/Users/GoogleAPI/googleads.yaml')
parser = argparse.ArgumentParser(
description="Lists all campaigns for specified customer."
)
# The following argument(s) should be provided to run the example.
parser.add_argument(
"-c",
"--customer_id",
type=str,
required=True,
help="The Google Ads customer ID.",
)
args = parser.parse_args()
print(args.customer_id)
main(google_ads_client, args.customer_id)
But I get this error.
errors {
error_code {
authorization_error: USER_PERMISSION_DENIED
}
message: "User doesn\'t have permission to access customer. Note: If you\'re accessing a client customer, the manager\'s customer id must be set in the \'login-customer-id\' header. See https://developers.google.com/google-ads/api/d
ocs/concepts/call-structure#login-customer-id"
}
customer id works fine for google adwords api.
If anyone knows the answer, I would appreciate it if you let me know.
Thank you.
The only thing you need is to pass the CustomerID without dash (-). More specifically, you just need passing the CustomerID with XXXXXXXXXX format instead of XXX-XXX-XXXX. The documentation isn't that informative!

Python code for resource groups code deletion in azure using Resource group tags

I am trying to delete the resource groups and resources in it using python code.
I have tried this in powershell and it works perfect. Now my organization wanted in Python. I am really new to python and trying to write the code and failed .
Here is the powershell code for the same. Can anyone help on getting the code in python.
Thanks in advance.
$rgs = Get-AzureRmResourceGroup;
# $rgs=Get-AzureRmResourceGroup -name "TestResourceGroupToClean1";
if(!$rgs)
{
Write-Output "No resource groups in your subscription";
}
else{
Write-Output "You have $($(Get-AzureRmResourceGroup).Count) resource groups in your subscription";
foreach($resourceGroup in $rgs)
{
$name= $resourceGroup.ResourceGroupName;
if($resourceGroup.Tags.ExpiryDate)
{
try{
$ResourceGroupTagDate=[datetime]::ParseExact($resourceGroup.Tags.ExpiryDate,'MM/dd/yyyy',$null)
$count = (Get-AzureRmResource | where { $_.ResourceGroupName -match $name }).Count;
if($ResourceGroupTagDate.Date -lt $today.Date)
{
$subject="Automated Mail from Resource Group Cleaner"
$body="Resource Group $($resourceGroup.ResourceGroupName) including resources has been deleted"
Write-Output "The resource group $name has $count resources. Deleting it...";
Remove-AzureRmResourceGroup -Name $resourceGroup.ResourceGroupName -Force;
Write-Output "The resource group $name and $count resources. Deleted..";
Send-MailMessage -To 'XXXX#XXXXXXXX.com' -Subject $subject -Body $body -UseSsl -Port 587 -SmtpServer 'smtp.office365.com' -From $userid -Credential $creds
}
}
Here is the Error I am getting ############################# Failed Traceback (most recent call last): File "C:\Temp\kukzwo13.tgf\9bd12580-5780-4109-abab-66e88fb4df87", line 59, in if not item.tags['ExpiryDate']:KeyError: 'ExpiryDate'
In python code, we need to check the key is valid for the dictionary. I have done a demo for deleting the resource group by tags with python code.
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
import datetime
from datetime import time
# Tenant ID for your Azure Subscription
TENANT_ID = 'tenant id '
# Your Service Principal App ID
CLIENT = 'client id'
# Your Service Principal Password
KEY = 'scret key'
subscription_id = 'subscrptionId'
credentials = ServicePrincipalCredentials(client_id=CLIENT, secret=KEY, tenant=TENANT_ID)
client = ResourceManagementClient(credentials, subscription_id)
groups = client.resource_groups.list()
null_variable = None
for item in groups:
if item.tags != null_variable:
if 'ExpiryDate' in item.tags:
expiryDate = datetime.datetime.strptime(item.tags["ExpiryDate"],"%m/%d/%Y")
timediff = expiryDate < datetime.datetime.today()
if timediff:
print(item.tags["ExpiryDate"])
print(item.name)
client.resource_groups.delete(item.name)
I would start with the sample page:
https://github.com/Azure-Samples/resource-manager-python-resources-and-groups
and the docs for support
https://learn.microsoft.com/en-us/python/azure/?view=azure-python

How to work with slackbot in python?

I am trying to build a slackbot for my group , I tried sample codes and some other things but its not sending message to the group.
first i tried via terminal
export SLACK_API_TOKEN="my_token_id"
Then
from slackclient import SlackClient
import os
slack_token = os.environ["SLACK_API_TOKEN"]
sc = SlackClient(slack_token)
sc.api_call(
"chat.postMessage",
channel="#random",
text="Hello from Python! :tada:",
thread_ts="283.5127(dummy_id)",
reply_broadcast=False
)
print(sc)
#<slackclient.client.SlackClient object at 0x109b77ba8>
But there is no message in slack group.
I tried with this code:
from slackclient import SlackClient
import os
slack_token = os.environ['SLACK_API_TOKEN']
sc = SlackClient(slack_token)
print(sc.api_call("channels.list"))
its retuning :
{'error': 'invalid_auth', 'ok': False}
I am not getting what i am doing wrong , Access token is correct , i want to post some messages via a bot , so how i can create a bot on slack and using that bot i can send messages via python ?
I had similar issues when I implemented a slack bot with php & symfony.
It's not that simple to create and configure the slack app, bot and OAuth permissions properly.
I explained all these configurations in this blog post if you need it: https://blog.eleven-labs.com/en/en/replace-erp-by-slack-bot-with-dialogflow-and-symfony/
Also my code in PHP is very similar to what you need to parse Slack requests and post to its API.
Summary, TL;DR:
Go to https://api.slack.com/apps and click on 'Create New App'.
In this app configuration, go to the left menu 'Bot Users' or from 'Basic Information' > 'Add features and functionality' > 'Bots'.
Still in this app config, go to the menu 'OAuth & Permissions' and allow the scope 'chat:write:bot' and copy the value of 'OAuth Access Token'
From your code, call 'chat.postMessage' API method with an 'Authorization' header using previous token value.
built this from some examples found on the web: liza daly - brobot : github.com
and
How to Build Your First Slack Bot with Python : fullstackpython.com
certainly not the best implementation but it functions as an appropriate answer to (i think)
import random
import time
import re
from slackclient import SlackClient
bot_id = None
slack_token = 'xoxb-no.more.mister.nice.gui'
sc = SlackClient(slack_token)
# constants
RTM_READ_DELAY = 1 # 1 second delay between reading from RTM
DEFAULT_RESPONSE = "greetings: 'hello', 'hi', 'greetings', 'sup', 'what's up' / commands: 'do'"
DEFAULT_COMMAND = "do"
MENTION_REGEX = "^<#(|[WU].+?)>(.*)"
def parse_bot_commands(slack_events):
"""
parses a list of events coming from the slack rtm api to find bot commands
:param slack_events:
:return:
"""
for event in slack_events:
if event["type"] == "message" and not "subtype" in event:
user_id, message = parse_direct_mention(event["text"])
if user_id == bot_id:
return message, event["channel"]
return None, None
def parse_direct_mention(message_text):
"""
finds direct message and returns user id
:param message_text:
:return:
"""
matches = re.search(MENTION_REGEX, message_text)
# the first group contains the user name, the second group contains
# the remaining message
return (matches.group(1), matches.group(2).strip()) if matches else (None, None)
def handle_command(command, channel):
"""
executes bot command if the command is known
:param command:
:param channel:
:return:
"""
GREETING_KEYWORDS = ("hello", "hi", "greetings", "sup", "what's up",)
GREETING_RESPONSES = ["'sup brah", "hey", "*headnod*", "didjageddathingahsencha?"]
# default response is help text for the user
default_response = "Not sure what you mean. Try *{}*.".format(DEFAULT_RESPONSE)
# finds and executes the given command, filling the response
response = None
#implement more commands below this line
if command in GREETING_KEYWORDS:
response = random.choice(GREETING_RESPONSES)
else:
if command.startswith(DEFAULT_COMMAND):
response = "Sure...write some more code and I'll do that"
# Sends the response back to the channel
sc.api_call(
"chat.postMessage",
channel="#the_danger_room",
as_user="true:",
text=response or default_response)
if __name__ == "__main__":
if sc.rtm_connect(with_team_state=False):
print("Connected and running!")
#call web api method auth.test to get bot usre id
bot_id = sc.api_call("auth.test")["user_id"]
while True:
command, channel = parse_bot_commands(sc.rtm_read())
if command:
handle_command(command, channel)
time.sleep(RTM_READ_DELAY)
else:
print("Connection failed. Exception traceback printed above.")

GraphAPI error in Facebook python SDK: An active access token must be used to query information about the current user

I'm using the Facebook SDK for python to programmatically post photos to a fan page I manage. Everything works perfectly locally, but fails in production with the error: GraphAPIError: An active access token must be used to query information about the current user.
Tinkering around shows me that the access_token and facebook_page_id are coming up as None in the code. That's weird because I've set them as environment variables on my server - writing env in the terminal shows them correctly set. I originally added them to .profile and then used the source command. I'm trying to import them in the code via os.environ.get('FACEBOOK_PAGE_ID') and os.environ.get('FACEBOOK_ACCESS_TOKEN'). What else can I do? It works perfectly fine if I hardcode the values in my code.
Here's my full code:
import facebook, os
def photo_poster(image_obj=None, caption=None):
PAGE_ID = os.environ.get('FACEBOOK_PAGE_ID')
ACCESS_TOKEN = os.environ.get('FACEBOOK_ACCESS_TOKEN')
cfg = {
"page_id" : PAGE_ID, # Step 1
"access_token" : ACCESS_TOKEN # Step 3
}
api = get_api(cfg)
status = api.put_photo(image=(image_obj),message=caption)
def get_api(cfg):
graph = facebook.GraphAPI(cfg['access_token'])
resp = graph.get_object('me/accounts')
page_access_token = None
for page in resp['data']:
if page['id'] == cfg['page_id']:
page_access_token = page['access_token']
graph = facebook.GraphAPI(page_access_token)
return graph
In .profile I've included the following lines:
export FACEBOOK_PAGE_ID=12345678
export FACEBOOK_ACCESS_TOKEN=ADAFASFGASGfsadfsadf4
(dummy values are shown)

Categories