Find

Announcement
· Sep 12, 2024

共有開発環境でGITを使用する

Git を使用してIRIS でソリューションを構築することは、素晴らしいことです! 単にローカルの git リポジトリにVSCodeを使用し、サーバーに変更をプッシュする... それは非常に簡単です。

でも、次の場合はどうでしょうか。

  • 共有リモート開発環境で他の開発者と共同作業を行い、同じファイルの同時編集を回避したい場合
  • BPL、DTL、ピボット、ダッシュボードなどにおいて管理ポータルに基づくエディターを使用しており、 作業に簡潔なソース管理を使用したい場合
  • 一部の作業においては引き続き Studio を使用しているかたまに VSCode から Studio に戻っているか、チームがまだ VSCode を完全に採用しておらず、一部のチームメンバーが Studio の使用を希望している場合
  • 同じネームスペースで同時に多数の独立したプロジェクト(InterSystems Package Manager を使って定義された複数のパッケージなど)に取り組んでおり、(多数の個別のプロジェクトではなく)1 つの isfs 編集ビューからすべてのプロジェクトの作業を行い、適切な git リポジトリで変更を自動的に追跡する場合

このような状況では、あまり簡単なオペレーションとは言えませんでした。ただし、先月末に Git for Shared Development Environments(Open Exchange / GitHubがリリースされるまでは、です。この拡張機能は、InterSystems パッケージマネージャーを使って入手できます。

zpm "install git-source-control"

これがリリースされる前は、Git によるソース管理のオプションは、ほぼ Windows 限定かローカル開発環境限定の古い Git 拡張機能これに基づいた若干使用方法が合理化されているより最近の Open Exchange プロジェクトでした。 また、ファイルを処理するだけのバージョン管理システムに依存しない Port もあります。

git-source-control にあり、これらのパッケージには含まれないものとは何でしょうか?

  • あらゆるオペレーティングシステムで動作する単純なメニューベースの git 統合
  • リモート環境に SSH 通信することなく、増大する一連の共通 git アクティビティに対応する git ユーザーインターフェース
  • 同じ環境で同時に作業する複数のユーザーを処理する並列制御。 クラスやルーチンなどに変更を行ったら、変更を破棄するかコミットするまでローカルに留まります。 (ただし、必要に応じて回避する方法があります!)
  • パッケージマネージャー対応: zpm "load -dev /path/to/package" を行って、/path/to/package/.git が存在する場合は、パッケージのリソースへの変更はサーバーのファイルシステムの適切な場所に自動的に反映されます。 UI も、それが起動された class/etc に基づいて動作します。

このすべては VSCode より動作します。

 
スポイラー

Studioからは以下の通り。

 
スポイラー

git リポジトリを操作したり視覚的に状況をみるには

 
スポイラー

これを使って、IRIS ベースのソリューションの開発がうまくいけば幸いです。フィードバックをお待ちしています!

注意 - 2021 Global Summit でのこのリリースのプレゼンテーションをご覧になるには、こちらの記事をご覧ください: https://community.intersystems.com/post/video-git-gitlab-shared-developm...

Discussion (0)1
Log in or sign up to continue
Article
· Sep 12, 2024 2m read

Code Scanner - enhanced

During testing the added Multi-Namespace feature I met a challenge
that required intervention. This simple request created 1000 lines of output.

USER>do ^rcc.find
----------------
 
enter search string [$ZU] <blank> to exit:
          Verbose? (0,1) [0]:
          Force UpperCase? (1,0) [1]:
 
enter code type (CLS,MAC,INT,INC,ALL) [ALL]:
 
select namespace (ALL,%SYS,DOCBOOK,ENSDEMO,ENSEMBLE,SAMPLES,USER) [USER]: all
  • As for the verbose variant you my run a log on your terminal to keep the result in details
  • though a real summary was still missing.

So I decided to append a very condensed statistic to the summary line

;;; skipping ~1000 lines of output
** 0 INC in Namespace USER**
 
** 1206 ** ALL total in Namespace USER
 
** 90120 ** total in ALL Namespaces
sub("%SYS")=10975
sub("%SYS","CLS")=2631
sub("%SYS","INC")=1433
sub("%SYS","INT")=6911
sub("%SYS","MAC")=0
sub("DOCBOOK")=27
sub("DOCBOOK","CLS")=27
sub("DOCBOOK","INC")=0
sub("DOCBOOK","INT")=0
sub("DOCBOOK","MAC")=0
sub("ENSDEMO")=45924
sub("ENSDEMO","CLS")=172
sub("ENSDEMO","INC")=10
sub("ENSDEMO","INT")=45687
sub("ENSDEMO","MAC")=55
sub("ENSEMBLE")=31504
sub("ENSEMBLE","CLS")=172
sub("ENSEMBLE","INC")=10
sub("ENSEMBLE","INT")=31280
sub("ENSEMBLE","MAC")=42
sub("SAMPLES")=484
sub("SAMPLES","CLS")=475
sub("SAMPLES","INC")=0
sub("SAMPLES","INT")=6
sub("SAMPLES","MAC")=3
sub("USER")=1206
sub("USER","CLS")=11
sub("USER","INC")=0
sub("USER","INT")=1192
sub("USER","MAC")=3
----------------

This summary I attached to the end show how and where the
90000+ hits are distributed. 

It works with the ALL namespace selection also for single code types

enter search string [$ZU] <blank> to exit:
          Verbose? (0,1) [0]:
          Force UpperCase? (1,0) [1]:
 
enter code type (CLS,MAC,INT,INC,ALL) [ALL]: mac
 
select namespace (ALL,%SYS,DOCBOOK,ENSDEMO,ENSEMBLE,SAMPLES,USER) [USER]: all
 
** Scan Namespace: %SYS **
 
** MAC **
 
** 0 MAC in Namespace %SYS**
 
** Scan Namespace: DOCBOOK **
 
** MAC **
 
** 0 MAC in Namespace DOCBOOK**
 
** Scan Namespace: ENSDEMO **
 
** MAC **
** 1      Ens.BusinessMetric.G1
** 41     EnsMONLBL
** 13     build
 
** 55 MAC in Namespace ENSDEMO**
 
** Scan Namespace: ENSEMBLE **
 
** MAC **
** 1      Ens.BusinessMetric.G1
** 41     EnsMONLBL
 
** 42 MAC in Namespace ENSEMBLE**
 
** Scan Namespace: SAMPLES **
 
** MAC **
** 3      rcc.find
 
** 3 MAC in Namespace SAMPLES**
 
** Scan Namespace: USER **
 
** MAC **
** 3      rcc.find
 
** 3 MAC in Namespace USER**
 
** 103 ** total in ALL Namespaces
sub("%SYS","MAC")=0
sub("DOCBOOK","MAC")=0
sub("ENSDEMO","MAC")=55
sub("ENSEMBLE","MAC")=42
sub("SAMPLES","MAC")=3
sub("USER","MAC")=3
----------------

try on Demo Server

Demo Server SMP
Demo Server WebTerminal
 

Discussion (0)2
Log in or sign up to continue
Announcement
· Sep 12, 2024

InterSystems IRIS SQL Specialist Exam is now LIVE!

Hello Community,

The Certification Team of InterSystems Learning Services is excited to announce the release of our new InterSystems IRIS SQL Specialist exam. It is now available for purchase and scheduling in InterSystems exam catalog. Potential candidates can review the exam topics and the practice questions to help orient them to exam question approaches and content. Candidates who successfully pass the exam will receive a digital certification badge that can be shared on social media accounts like LinkedIn.  <--break->If you are new to InterSystems Certification, please review our program pages that include information on taking examsexam policiesFAQ and more. Also, check out our Organizational Certification, which can help your organization access valuable business opportunities and establish itself as a reliable provider of InterSystems solutions in our marketplace. 

If you have ideas about creating new certifications that can help you advance your career, the Certification Team of InterSystems Learning Services is always open to ideas and suggestions. Please contact us at certification@intersystems.com if you would like to share any ideas.

Looking forward to celebrating your success, 

Emily Geary - Certification Operation Specialist, InterSystems

Discussion (0)1
Log in or sign up to continue
Article
· Sep 12, 2024 7m read

Embedded python in InterSystems IRIS

Hello Community,

In this article, I will outline and illustrate the process of implementing ObjectScript within embedded Python. This discussion will also reference other articles related to embedded Python, as well as address questions that have been beneficial to my learning journey.

As you may know, the integration of Python features within IRIS has been possible for quite some time. This article will focus on how to seamlessly incorporate ObjectScript with embedded Python.

Essentially, embedded Python serves as an extension that allows for independent writing and execution. It enables the seamless integration of Python code with ObjectScript and vice versa, allowing both to run within the same context. This functionality significantly enhances the capabilities of your implementation.

To begin, you must specify the language for your Python code within the class definition by using the "language" keyword [language = "python"]. Once this is done, you are prepared to write your Python code.

import iris - The iris package is a vital Python library that facilitates communication with InterSystems' native API classes, routines, globals, and SQL. This package is readily available by default. Anyway It is necessary to import this package at the beginning of your python code if you're going to interact with IRIS.

Few important notes before writing

  • You can use python special variable __name__ to refer the classname inside the class definition.
  • Use _ for %Methods ex: %New  == _New , %OpenId == _OpenId

Let's begin

Class members implementation in Embedded python

1.  Objects and Properties

This section is essential as it will cover the process of initializing a new object, altering the values of existing objects, and configuring properties in both static and dynamic contexts. Create your own class definition and use the simple literal properties

1.1 initialize new Object / Modify existing object

Use _New for initiate new object and _OpenId(id) for edit the existing object

ClassMethod SaveIRISClsObject() [ Language = python ]
{
 #this method calls the %OnNew callback method and get the object
 import iris
 try:
     iris_obj =  iris.cls(__name__)._New()
     if not iris.cls(__name__).IsObj(iris_obj):
      #IsObj is the objectscript wrapper method : which contains $Isobject()
         raise ReferenceError('Object Initlize Error')
 except ReferenceError as e:
     print(e)
     return
 #set the object properties and save the values
 iris_obj.Name = 'Ashok'
 iris_obj.Phone = 9639639635
 status = iris_obj._Save()
 print(status)
 return status
}

1.2 Accessing properties

Prior to commencing the property section, it is important to note that the IRIS data type differs from Python data types, and therefore, IRIS collection data types cannot be utilized directly within Python. To address this, InterSystems has offered a comprehensive solution for converting IRIS data types into Python-compatible formats such as lists, sets, and tuples. This can be achieved by importing the "builtins" module within the IRIS code base, utilizing the class methods ##class(%SYS.Python).Builtins() or by setting builtins = ##class(%SYS.Python).Import("builtins"). I'll cover this in upcoming sections.

So, I use this method to convert the $LB properties into python list for accessing the properties at runtime in python

LEARNING>Set pyList = ##class(%SYS.Python).ToList($LB("Name","Phone","City"))
 
LEARNING>zw pyList
pyList=5@%SYS.Python  ; ['Name', 'Phone', 'City']  ; <OREF>
ClassMethod GetProperties() [Language = objectscript]
{
    set pyList = ##class(%SYS.Python).ToList($LB("Name","Phone","City"))
    do ..pyGetPropertiesAtRunTime(pyList)
}
ClassMethod pyGetPropertiesAtRunTime(properties) [ Language = python ]
{
    import iris
    iris_obj = iris.cls(__name__)._OpenId(1)
    for prop in properties:
        print(getattr(iris_obj,prop))
}

 

1.3 Set properties at runtime.

I utilize this python dictionary to designate my property as a key and, with the corresponding property values serving as the values within that dictionary. You may refer to the code provided below and the community post regarding this property set.

ClassMethod SetProperties()
{
	Set pyDict = ##class(%SYS.Python).Builtins().dict()
	do pyDict.setdefault("Name1", "Ashok kumar")
	do pyDict.setdefault("Phone", "9639639635")
	do pyDict.setdefault("City", "Zanesville")
	Set st = ..pySetPropertiesAtRunTime(pyDict)
}

ClassMethod pySetPropertiesAtRunTime(properties As %SYS.Python) [ Language = python ]
{
	import iris
	iris_obj = iris.cls(__name__)._New()
	for prop in properties:
		setattr(iris_obj, prop,properties[prop])
	
	status = iris_obj._Save()
	return status
}

1.4 Object share context

As previously stated, both Python and ObjectScript operate within the same memory context and share objects. This implies that you can create or open an object in the InCache class and subsequently set or retrieve it in the Python class.

ClassMethod ClassObjectAccess() [Language = objectscript]
{
	Set obj = ..%OpenId(1)
	Write obj.PropAccess(),! ; prints "Ashok kumar"
	Do obj.DefineProperty("test")
	Write obj.PropAccess() ; prints "test"
}

Method PropAccess() [ Language = python ]
{
	
return self.Name
}

Method DefineProperty(name) [ Language = python ]
{
	
self.Name = name
}

2.  Parameters

Get the parameter arbitrary key value pair by using the _GetParameter. Refer the useful community post 

ClassMethod GetParam(parameter = "MYPARAM") [ Language = python ]
{
	import iris
	value = iris.cls(__name__)._GetParameter(parameter)
	print(value)
}

3. Class Method and Methods

3.1 Class Method

The invocation of class methods and functions is highly beneficial for executing the object script code.

Invoke the class method as a static call ex: Do ..Test() 

ClassMethod InvokeStaticClassMethods(clsName = "MyLearn.EmbeddedPython") [ Language = python ]
{
	import iris
	print(iris.cls(clsName).Test())
	# print(iris.cls(__name__).Test()) 
}


Invoke the Class method at runtime Set method="Test" Do $ClassMethod(class, method, args...)

ClassMethod InvokeClassMethodsRunTime(classMethod As %String = "Test") [ Language = python ]
{
 import iris
 clsMethodRef = getattr(iris.cls(__name__), classMethod) # will return the reference of the method
 print(clsMethodRef()) 
}

3.2  Methods

Invoke the instance methods are same as "object script" format. In the below code I've initiate the object first and call the instance method with parameters.

ClassMethod InvokeInstanceMethodWithActualParameters() [ Language = python ]
{
	import iris
	obj = iris.cls(__name__)._New()
	print(obj.TestMethod(1,2,4))
}

3.3  Pass arguments by value and reference b/w python and objectscript

Basically passing the arguments are inevitable between the functions and the same will remain between ObjectScript and python

3.4  Pass by value - It's as usual pass by value

ClassMethod passbyvalfromCOStoPY()
{
    Set name = "test", dob= "12/2/2002", city="chennai"
    Do ..pypassbyvalfromCOStoPY(name, dob, city)
}

ClassMethod pypassbyvalfromCOStoPY(name As %String, dob As %String, city As %String) [ Language = python ]
{
   print(name,'  ',dob,'  ',city)
}

/// pass by value from  python to object script
ClassMethod pypassbyvalfromPY2COS() [ Language = python ]
{
	import iris
	name = 'test'
	dob='12/2/2002'
	city='chennai'
	iris.cls(__name__).passbyvalfromPY2COS(name, dob, city)
}

ClassMethod passbyvalfromPY2COS(name As %String, dob As %String, city As %String)
{
    zwrite name,dob,city
}

3.5 Pass by reference- Unlike the pass by value. Since Python does not support call by reference natively, so, you need to use the iris.ref()  in python code to make it the variable as a reference. refer the reference. To the best of my knowledge, there are no effects on the object script side regarding pass-by-reference variables, even when these variables are modified in Python. Consequently, Python variables will be affected by this pass-by-reference mechanism when the methods of the object script are invoked

ClassMethod pypassbyReffromPY2COS() [ Language = python ]
{
	import iris
	name='python'
	dob=iris.ref('01/01/1991')
	city = iris.ref('chennai')
	print('before COS ',name,'  ',dob.value,'  ',city.value)
	#pass by reference of dob, city
	iris.cls('MyLearn.EmbeddedPythonUtils').passbyReffromPY2COS(name, dob, city)	
	print('after COS ',name,'  ',dob.value,'  ',city.value)
}

ClassMethod passbyReffromPY2COS(name, ByRef dob, ByRef city)
{
  Set name="object script", dob="12/12/2012", city="miami"
}

// output 
LEARNING>do ##class(MyLearn.EmbeddedPythonUtils).pypassbyReffromPY2COS()
before COS  python    01/01/1991    chennai
after COS  python    12/12/2012    miami
 


3.5 **kwargs- There is an additional support for passing the python keyword arguments (**kwargs) from object script. Since InterSystems IRIS does not have the concept of keyword arguments, you have to create a  %DynamicObject to hold the keyword/value pairs and pass the values as syntax Args...

I have created the dynamicObject  "name""ashok""city""chennai"}and set the required key-value pairs in it and eventually pass to the python code.

ClassMethod KWArgs()
{
    set kwargs={ "name": "ashok", "city": "chennai"}
    do ..pyKWArgs(kwargs...)
}

ClassMethod pyKWArgs(name, city, dob = "") [ Language = python ]
{
    print(name, city, dob)
}

// output
LEARNING>do ##class(MyLearn.EmbeddedPythonUtils).KWArgs()
ashok chennai

I will cover the global, routines and SQL in next article

1 Comment
Discussion (1)1
Log in or sign up to continue
Announcement
· Sep 12, 2024

[Video] Identifying Useful Components for Your Generative AI Application

Hi, Community!

What components and libraries can you add to your retrieval-augmented generation (RAG) applications? Find out in this video:

Identifying Useful Components for Your Generative AI Application

In this interview, InterSystems Sales Engineer @Elijah Cotterrell introduces the components you can leverage on top of your RAG applications, including:

  • Agents
  • Hugging Face data sets
  • Embedding models

Continue learning how to develop generative AI applications (learning path, 2h).

Discussion (0)1
Log in or sign up to continue