How to use flask babel gettext in celery? - celery

I have a flask-celery setup with flask babel translating my texts. I can't translate in celery tasks. I believe this is because it doesn't know the current language (I'm not it could even if it did) and this is because celery doesn't have access to the request context (from what i understood)...
What would be the solution to be able to translate?

You rightly pointed out that issue that is celery doesn't have access to request context, which means flask_babelex.get_locale returns None. You can use force_locale context manager available in Flask-Babel which provides dummy request context.
from contextlib import contextmanager
from flask import current_app
from babel import Locale
from ..config import SERVER_NAME, PREFERRED_URL_SCHEME
#contextmanager
def force_locale(locale=None):
if not locale:
yield
return
env = {
'wsgi.url_scheme': PREFERRED_URL_SCHEME,
'SERVER_NAME': SERVER_NAME,
'SERVER_PORT': '',
'REQUEST_METHOD': ''
}
with current_app.request_context(env) as ctx:
ctx.babel_locale = Locale.parse(locale)
yield
Sample Celery Task
#celery.task()
def some_task(user_id):
user = User.objects.get(id=user_id)
with force_locale(user.locale):
...gettext('TranslationKey')...

Related

setting os.environ in selenium4

I am a beginner in programming, and in selenium as well. Therefore, I am seeking for your help in fixing the code to set os.environ in selenium4 as below.
service = ChromeService(executable_path="D:\\port\\driver\\chromedriver")
os.environ["wedriver.chrome.driver"] = service
driver = webdriver.Chrome(service=service)
driver.get(https://gisgeography.com/free-satellite-imagery-data-list/')
driver.maximize_window()
You will not need to use an environment variable for this.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
s=Service('D:\\port\\driver\\chromedriver')
browser = webdriver.Chrome(service=s)
url='https://www.google.com'
browser.get(url)
however if you need to set ot read environment variables using python below is an example
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
# Setting an environment variable
os.environ["CHROME_DRIVER_PATH"] = "D:\\port\\driver\\chromedriver"
# Reading an environment variable
DRIVER_PATH = os.environ.get('CHROME_DRIVER_PATH')
s=Service(DRIVER_PATH)
browser = webdriver.Chrome(service=s)
url='https://www.google.com'
browser.get(url)

Mocking MongoDB for Testing REST API designed in Flask

I have a Flask application, where the REST APIs are built using flask_restful with a MongoDB backend. I want to write Functional tests using pytest and mongomock for mocking the MongoDB to test the APIs but not able to configure that. Can anyone guide me providing an example where I can achieve the same?
Here is the fixture I am using in the conftest.py file:
#pytest.fixture(scope='module')
def test_client():
# flask_app = Flask(__name__)
# Flask provides a way to test your application by exposing the Werkzeug test Client
# and handling the context locals for you.
testing_client = app.test_client()
# Establish an application context before running the tests.
ctx = app.app_context()
ctx.push()
yield testing_client # this is where the testing happens!
ctx.pop()
#pytest.fixture(autouse=True)
def patch_mongo():
db = connect('testdb', host='mongomock://localhost')
yield db
db.drop_database('testdb')
disconnect()
db.close()
and here is the the test function for testing a post request for the creation of the user:
def test_mongo(test_client,patch_mongo):
headers={
"Content-Type": "application/json",
"Authorization": "token"
}
response=test_client.post('/users',headers=headers,data=json.dumps(data))
print(response.get_json())
assert response.status_code == 200
The issue is that instead of using the testdb, pytest is creating the user in the production database. is there something missing in the configuration?

how to detect if your code is running under pyspark

For staging and production, my code will be running on PySpark. However, in my local development environment, I will not be running my code on PySpark.
This presents a problem from the standpoint of logging. Because one uses the Java library Log4J via Py4J when using PySpark, one will not be using Log4J for the local development.
Thankfully, the API for Log4J and the core Python logging module are the same: once you get a logger object, with either module you simply debug() or info() etc.
Thus, I wish to detect whether or not my code is being imported/run in PySpark or a non-PySpark environment: similar to:
class App:
def our_logger(self):
if self.running_under_spark():
sc = SparkContext(conf=conf)
log4jLogger = sc._jvm.org.apache.log4j
log = log4jLogger.LogManager.getLogger(__name__)
log.warn("Hello World!")
return log
else:
from loguru import logger
return logger
How might I implement running_under_spark()
Simply trying to import pyspark and seeing if it works is not a fail-proof way of doing this because I have pyspark in my dev environment to kill warnings about non-imported modules in the code from my IDE.
Maybe you can set some environment variable in your spark environment that you check for at runtime ( in $SPARK_HOME/conf/spark-env.sh):
export SPARKY=spark
Then you check if SPARKY exists to determine if you're in your spark environment.
from os import environ
class App:
def our_logger(self):
if environ.get('SPARKY') is not None:
sc = SparkContext(conf=conf)
log4jLogger = sc._jvm.org.apache.log4j
log = log4jLogger.LogManager.getLogger(__name__)
log.warn("Hello World!")
return log
else:
from loguru import logger
return logger

HttpClient not found in elastic4s?

I am getting below error while using HttpClient. Can you let me know how to use HttpClient exactly. I am new with elastic4s.
I want to connect scala with ssl configured elasticsearch. I also want to know how I can pass SSL details with link such as keystore path, truststore path and user name , password.
scala> import com.sksamuel.elastic4s.http.{HttpClient, HttpResponse}
import com.sksamuel.elastic4s.http.{HttpClient, HttpResponse}
scala> import com.sksamuel.elastic4s.http.ElasticDsl._
import com.sksamuel.elastic4s.http.ElasticDsl._
scala> val client = HttpClient(ElasticsearchClientUri(uri))
<console>:39: error: not found: value HttpClient
val client = HttpClient(ElasticsearchClientUri(uri))
HttpClient appears to be a trait in the codebase.You seem to be using the same as an object. You can check the implementation Here. For your use case i think the better approach would be to use ElasticClient. Code would look something like this
import com.sksamuel.elastic4s.http._
import com.sksamuel.elastic4s.{ElasticClient, ElasticDsl, ElasticsearchClientUri}
val client = elastic4s.ElasticClient(ElasticsearchClientUri(uri))
I got the same problem, i.e. in my setup I got errors (not found) when trying to use HttpClient (elastic4s-core,elastic4s-http-streams and elastic4s-client-esjava version 7.3.1 on scala 2.12.10).
The solution: you should be able to find and use JavaClient, an implementation of HttpClient that wraps the Elasticsearch Java Rest Client.
An example of how to use the JavaClient can be found here.
Thus, your code should look like the following:
import com.sksamuel.elastic4s.http.JavaClient
import com.sksamuel.elastic4s.{ElasticClient, ElasticDsl, ElasticProperties}
...
val client = ElasticClient(JavaClient(ElasticProperties(uri)))

scala cloud foundry mongodb : access to mongodb denied

I have installed eclipse, the cloudfoundry plugin, the scala plugin,the vaadin plugin(for web developments) and the mongodb libraries.
I created a class like this :
import vaadin.scala.Application
import vaadin.scala.VerticalLayout
import com.mongodb.casbah.MongoConnection
import com.mongodb.casbah.commons.MongoDBObject
import vaadin.scala.Label
import vaadin.scala.Button
class Launcher extends Application {
val label=new Label
override def main = new VerticalLayout() {
val coll=MongoConnection()("mybd")("somecollection")
val builder=MongoDBObject.newBuilder
builder+="foo1" -> "bar"
var newobj=builder.result()
coll.save(newobj)
val mongoColl=MongoConnection()("mybd")("somecollection")
val withFoo=mongoColl.findOne()
label.value=withFoo
add(label)
//bouton pour faire joli
add(new Button{
caption_=("click me!")
})
}
}
the error (the access to the mongodb database is denied) comes from the parameters, which are the default ones.
do you know how to set up the good parameters in scala or in java?
Looks like you got some help on the vcap-dev mailing list
package com.example.vaadin_1
import vaadin.scala.Application
import org.cloudfoundry.runtime.env.CloudEnvironment
import org.cloudfoundry.runtime.env.MongoServiceInfo
import com.mongodb.casbah.MongoConnection
class Launcher extends Application {
val cloudEnvironment = new CloudEnvironment()
val mongoServices = cloudEnvironment.getServiceInfos(classOf[MongoServiceInfo])
val mongo = mongoServices.get(0)
val mongodb = MongoConnection(mongo.getHost(), mongo.getPort())("abc")
mongodb.authenticate(mongo.getUserName(),mongo.getPassword())
}
I would suggest to do it using Spring Data for MongoDB there is a sample application for Cloudfoundry in particular put together by the Spring guys. With a bit of xml configuration you have ready to inject the mongoTemplate similar to the familiar Spring xxxTemplate paradigm.
when deploying to CloudFoundry, the information relative to connecting to a service (i.e mongo in your case) is made available to the app through environment variable VCAP_SERVICES. It is a json document with one entry per service. You could of course parse it yourself, but you will find the class http://cf-runtime-api.cloudfoundry.com/org/cloudfoundry/runtime/env/CloudEnvironment.html useful. You will need to add the org.cloudfoundry/cloudfoundry-runtime/0.8.1 jar to your project. You can use it without Spring.
Have a look at http://docs.cloudfoundry.com/services.html for explanation of the VCAP_SERVICES underlying var