aidbox / aidbox-python-sdk Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Let's make subscription callback more high-level:
def patient_send_email_on_create(action, resource):
pass
where action
is current event['action'] and resource is an instance of AidboxResource from event['resource']
And the current logic with the decorator is confusing. Let's initialize manifest somehow with subscription definitions:
subscriptions = {
'Patient': [patient_send_email_on_create, sub2, ...]
}
sdk = SDK(
sdk_settings,
entities=entities,
resources=meta_resources,
seeds=seeds,
migrations=migrations,
subscriptions=subscriptions,
on_ready=on_ready)
Using decorator allows having only one subscription and decorators can be used in any file so that makes impossible to understand the whole picture how the app works.
Now we have a problem when we want to make additional business logic on some actions, e.g. Patient creation.
We used two methods:
Custom operation is good enough and it should be used for complex logic.
Subscription isn't good for business logic (especially mutating) because of non-atomic nature: we can't unroll resource creation/updating/deletion when something went wrong in the subscription.
Discussed with @ir4y we decided that we need something new - FHIR operation overriding.
Proposal:
POST /Patient
might be overridden with a custom operation where we can call super method.
It means we need something like POST /original/{resource-type} (URL need to be discussed).
Now we always do whole app initialization. Whan app starts it should check that local manifest matches app manifest. If they are the same we should start the app without initialization phase.
async def healthcheck():
return web.json_response({'is_ready': sdk.is_ready.result()})
https://github.com/Aidbox/aidbox-python-sdk/blob/master/aidbox_python_sdk/pytest_plugin.py#L11
Was it done explicitly or by mistake?
Before the upgrade, it wasn't a problem to run tests on python 3.9 and old aidbox python SDK
Hello! I am trying to use and SDK but get the following error during app initializaion - Response from Aidbox: 500 {"message":"No manifest provided"}
Here are my findings of possible reasons:
in aidbox_python_sdk/main.py
the manifest looks the follwoing:
json = {
'url': app['settings'].APP_URL,
'app_id': app['settings'].APP_ID,
'secret': app['settings'].APP_SECRET,
}
However Aidbox documentation suggest more diverse object:
resourceType: App
id: myorg.myapp # id of your application
apiVersion: 1 # App API version
type: app # type of app - app | addon
endpoint: # communication protocol between aidbox and app
type: http-rpc # type of protocol - http-rpc | ws-rpc
host: app.mydomain.com # app service host for http protocols
scheme: https # app service schema for http protocols - default = https
port: 8080 # app service port - default = 80
secret: <yoursercret> # will be used to secure aidbox - app communication
entities: <Resource's Definitions, Profiles & Hooks>
operations: <Operation's Definitions>
subscriptions: <Subscriptions>
It this mismatch a source of error?
Can you please facilitate with fixing this. Thanks!
The function create_app
should wait for config
Aidbox initializing message.
App subscriptions don't guarantee receiving
Now we have operation
and request
args, but operation
isn't useful for endpoints. I think request
should be the first argument.
This argument accept JSON AccessPolicy schema and apply it for the operation
Currently, type hints are not defined. I suggest adding typehints for them. Since some projects are using python3.9, let's write types using python3.9+
Let's make them available via sqlalchemy.func by default (project independent):
@ir4y What do you think? They can be useful for custom endpoints with sqlalchemy.
Sometimes we need to use client/db outside, e.g. in corn tasks.
We need to add an example to readme how to achieve it.
One of the possible solutions:
And use in the cron as:
@crontab("* * * * *")
async def import_hospital_data_task_opoo():
async with init_client(sdk_settings) as client:
await client.resources('Patient').fetch()
The only thing that needs to be solved, is how to get rid of settings here, maybe always passing SDK object that already contains settings
There is an issue with pytest. It is partially fixed now at this branch https://github.com/Aidbox/aidbox-python-sdk/tree/update-python-3-11
Unfortunately, aidbox initializes on each test. It should be fixed. Aidbox should be initialized only once per test suite run.
Health checks on productions fill logs and make it total unreadable
It's redundant. Use APP_INIT_URL always
raw_sql should raise an error or return the result without wrappers from Aidbox
New types should be added, somethling like:
class SDKOperationRequestApp(TypedDict):
client: AsyncAidboxClient
db: DBProxy
sdk: SDK
class SDKOperationRequest(TypedDict):
app: SDKOperationRequestApp
And sdk.operation
/sdk.subscription
should return function with SDKOperationRequest
typehint
Usage example:
@sdk.operation(["POST"], ["$myop"])
async def myop_op(_operation, request: SDKOperationRequest):
client = request["app"]["client"]
return web.json_response({})
Check if we can add Operation.description in app manifest.
This feature should be optional (we can set flag for this in ENV file)
Creating default resource via Manifest overrides resource value even if it was modified after
pervious deploy. It is useful to have an option to seed resource value just once.
request
arg in operation - it's request from aidbox (dict)request
arg in subscription - it's an aiohttp requestIf an app can't connect to the AidBox, it should fail and stop working.
Now app continue working, so it accepts hooks requests from AidBox and fails in runtime.
/Entity?type=resource
and bootstrap SQL Alchemy models at runtimemanifest.alchemy
as entrypint for SQL Alchemy based queriesmanifest.raw_sql
as entrypint for raw SQL request as stringsNow it's difficult to debug issues if backend fails with exception (e.g. KeyError):
@sdk.operation(..)
def operation(_, request):
key = request['resource']['userType']
...
If we don't pass userType - the code fails, and Aidbox returns 500 without details.
Let's add some useful information for DEV environment (stack trace + error message)
Example:
async def raw_update(resource: AsyncAidboxResource):
cleaned_resource = funcy.omit(
resource.serialize(), ['resourceType', 'id', 'meta'])
if 'meta' in resource:
cleaned_meta = funcy.omit(
resource['meta'], ['versionId', 'lastUpdated'])
if cleaned_meta:
cleaned_resource['meta'] = cleaned_meta
table = getattr(sdk.db, resource.resource_type).__table__
stmt = table.update().where(table.c.id == resource.id).values(
resource=cleaned_resource,
status='updated',
ts=sqlalchemy.func.now()).returning(table)
await sdk.db.alchemy(stmt)
for resource = {"field": "content \" "}
I always get an error.
When the app tries to connect to aidbox https://github.com/Aidbox/aidbox-python-sdk/blob/with-aidbox-py/aidbox_python_sdk/main.py#L52 it uses the default timeout.
In a kubernetes cluster, it gets a timeout for the first request and it takes about 5 minutes.
Let's restore timeout set to 3 seconds and fail if it reached 670361d
In the proves of new deploy, It is possible that application gets a request from the AidBox but, it will not be initialized yet. In this case, SDK should respond to AidBox with 503 code, instead of a passing request to the handler.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.