is there a way to destructor the self object like javascript? - python-3.x

I've started to write python, and I come into the self that you write inside of a class.
def start_simulator(self):
while True:
cloud = o3d.io.read_point_cloud(str(i) + '.ply')
self.vis.clear_geometries()
self.vis.add_geometry(cloud)
self.vis.poll_events()
self.vis.update_renderer()
if self.inputQueue.qsize() > 0:
input_str = self.inputQueue.get()
if input_str == "stop":
self.inputQueue.empty()
break
now I see myself writing a lot of self.
is there a way to use a destructor to self? Like in javascript:
const hero = {
name: 'Batman',
realName: 'Bruce Wayne'
};
const { name, realName } = hero; //something like this
Thanks for the help.

you can use dataclasses decorator in python its the closest data structure in python i know
from dataclasses import dataclass
#dataclass
class hero:
name: str
realName: str
you can check this website:
https://realpython.com/python-data-classes/

Related

Repeated checking of ID path parameter in FastAPI

I have the following route specs:
GET /councils/{id}
PUT /councils/{id}
DELETE /councils/{id}
In all three routes, I have to check in the database whether the council with the id exists, like this:
council = crud.council.get_by_id(db=db, id=id)
if not council:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail='Council not found'
)
Which adds to a lot of boilerplate in the code. Is there any way of reducing this? I have thought of creating a dependency but then I have to write different dependency function for different models in my database. Is there any standard practice for this?
Thanks.
Using a dependency is the way to go - it allows you to extract the logic around "get a valid council from the URL"; you can generalize it further if you want to map /<model>/<id> to always retrieving something from a specific model; however - you might want to validate this against a set of possible values to avoid people trying to make you load random Python identifiers in your models class.
from fastapi import Path
def get_council_from_path(council_id: int = Path(...),
db: Session = Depends(get_db),
):
council = crud.council.get_by_id(db=db, id=id)
if not council:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail='Council not found'
)
return council
#app.get('/councils/{council_id}')
def get_council(council: Council = Depends(get_council_from_path)):
pass
You can generalize the dependency definition to make it reusable (I don't have anything available to test this right now, but the idea should work):
def get_model_from_path(model, db: Session = Depends(get_db)):
def get_model_from_id(id: int = Path(...)):
obj = model.get_by_id(db=db, id=id)
if not council:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail='{type(model)} not found'
)
return get_model_from_id
#app.get('/councils/{id}')
def get_council(council: Council = Depends(get_model_from_path(crud.council)):
pass
Here is one solution that works. FastAPI supports classes as dependencies. Therefore I can have a class like this:
class DbObjIdValidator:
def __init__(self, name: str):
if name not in dir(crud):
raise ValueError('Invalid model name specified')
self.crud = getattr(crud, name)
def __call__(self, db: Session = Depends(get_db), *, id: Any):
db_obj = self.crud.get_by_id(db=db, id=id)
if not db_obj:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail='not found'
)
return db_obj
Considering crud module imports the crud classes for all the ORM models. My example is closely following the fastAPI cookiecutter project by Tiangolo, and the crud design pattern he followed.
Now in order to use it, for example in councils_route.py, I can do the following:
router = APIRouter(prefix='/councils')
council_id_dep = DbObjIdValidator('council') # name must be same as import name
#router.get('/{id}', response_model=schemas.CouncilDB)
def get_council_by_id(
id: UUID,
db: Session = Depends(get_db),
council: Councils = Depends(council_id_dep)
):
return council

FastAPI + Strawberry GraphQL Filter Conditions

I am currently build microservice using FastAPI + Strawberry GraphQL. I want to expose filters for the models with and/or condition. For example,
{
Student(where:{and[{AgeGt: 15},{PercentageLt: 75}]}) {
edges {
node {
Name
Age
Percentage
}
}
}
Is this possible? Any reference or example would greatly help.
In Strawberry you can use input types to define arguments for your queries
Here's an example what should help you with definining filters using strawberry:
from typing import Optional, List, TypeVar, Generic
from datetime import date
import strawberry
T = TypeVar("T")
#strawberry.input
class AbelFilter(Generic[T]):
eq: Optional[T] = None
gt: Optional[T] = None
lt: Optional[T] = None
#strawberry.input
class WhereFilter:
foo: Optional[AbelFilter[str]] = None
bar: Optional[AbelFilter[int]] = None
baz: Optional[AbelFilter[str]] = None
#strawberry.type
class Query:
#strawberry.field
def student(self, where: WhereFilter) -> str:
return str(where)
schema = strawberry.Schema(query=Query)
See this on the Strawberry Playground

fastapi how to read nested json as dictionary?

I am trying to receive the following JSON:
{
"va": "{1: 5, 2:1, 3:5}"
}
in my main.py I have the following:
from typing import Optional, Dict
from fastapi import FastAPI
from pydantic import BaseModel
class rq(BaseModel):
va: Dict[str, str]
app = FastAPI(debug=True)
#app.post("/hello")
async def create_item(rq: rq):
return 1
but I get
"msg": "value is not a valid dict",
"type": "type_error.dict"
how may I receive va as dict to iterate over it?
When you create a model, every field is actually a key-value pair, so with your example it expects something like this:
{
"va": {"some":"value"}
}
But what you send is
"va": str
So i don't know how you send the value but you are definitely sending a str instead of a Dict[str, str]

Getting variables from a different file in Jenkins Pipeline

I have a contants.groovy file as below
def testFilesList = 'test-package.xml'
def testdataFilesList = 'TestData.xml'
def gitId = '9ddfsfc4-fdfdf-sdsd-bd18-fgdgdgdf'
I have another groovy file that will be called in Jenkins pipeline job
def constants
node ('auto111') {
stage("First Stage") {
container('alpine') {
script {
constants = evaluate readTrusted('jenkins_pipeline/constants.groovy')
def gitCredentialsId = constants."${gitId}"
}
}
}
}
But constants."${gitId}" is says "cannot get gitID from null object". How do I get it?
It's because they are local variables and cannot be referenced from outside. Use #Field to turn them into fields.
import groovy.transform.Field
#Field
def testFilesList = 'test-package.xml'
#Field
def testdataFilesList = 'TestData.xml'
#Field
def gitId = '9ddfsfc4-fdfdf-sdsd-bd18-fgdgdgdf'
return this;
Then in the main script you should load it using load step.
script {
//make sure that file exists on this node
checkout scm
def constants = load 'jenkins_pipeline/constants.groovy'
def gitCredentialsId = constants.gitId
}
You can find more details about variable scope in this answer

Why am I getting StackOverflowError?

In Groovy Console I have this:
import groovy.util.*
import org.codehaus.groovy.runtime.*
def gse = new GroovyScriptEngine("c:\\temp")
def script = gse.loadScriptByName("say.groovy")
this.metaClass.mixin script
say("bye")
say.groovy contains
def say(String msg) {
println(msg)
}
Edit: I filed a bug report: https://svn.dentaku.codehaus.org/browse/GROOVY-4214
It's when it hits the line:
this.metaClass.mixin script
The loaded script probably has a reference to the class that loaded it (this class), so when you try and mix it in, you get an endless loop.
A workaround is to do:
def gse = new groovy.util.GroovyScriptEngine( '/tmp' )
def script = gse.loadScriptByName( 'say.groovy' )
script.newInstance().with {
say("bye")
}
[edit]
It seems to work if you use your original script, but change say.groovy to
class Say {
def say( msg ) {
println msg
}
}

Resources