Buscar

Limpiar filtro
Artículo
Ricardo Paiva · 4 mayo, 2023

Detección de texto generado mediante IA usando IntegratedML

En los últimos años, las tecnologías de inteligencia artificial para la generación de texto han avanzado significativamente. Por ejemplo, los modelos de generación de texto basados en redes neuronales pueden producir textos que son casi indistinguibles de los textos escritos por humanos. ChatGPT es uno de estos servicios. Es una enorme red neuronal entrenada con una gran cantidad de textos, que puede generar textos sobre varios temas y adaptarse a un contexto dado. La nueva tarea para las personas es desarrollar formas de reconocer textos escritos no solo por personas sino también por inteligencia artificial (IA). Esto se debe a que, en los últimos años, los modelos de generación de texto basados en redes neuronales se han vuelto capaces de producir textos que son casi indistinguibles de los textos escritos por humanos. Hay dos métodos principales para el reconocimiento de texto escrito por inteligencia artificial (IA): Utilizar algoritmos de machine learning para analizar las características estadísticas del texto; Utilizar métodos criptográficos que pueden ayudar a determinar la autoría del texto En general, la tarea de reconocimiento de texto de IA es difícil pero importante. Me complace presentar una aplicación para el reconocimiento de textos generados por inteligencia artificial (IA). Durante el desarrollo, aproveché los beneficios de InterSystems Cloud SQL e Integrated ML, que incluyen: Solicitudes de datos rápidas y eficientes, con alto rendimiento y velocidad; Interfaz amigable para usuarios no expertos en bases de datos y machine learning; Escalabilidad y flexibilidad para ajustar rápidamente los modelos de ML según los requisitos; En el desarrollo y entrenamiento posterior del modelo, utilicé un conjunto de datos abierto, concretamente 35 mil textos escritos. La mitad de los textos fueron escritos a mano por un gran número de autores, y la otra mitad fue generada por IA con ChatGPT. Configuración usada para el modelo GPT: model="text-curie-001" temperature=0.7 max_tokens=300 top_p=1 frequency_penalty=0.4 presence_penalty=0.1 A continuación, se establecieron unos 20 parámetros básicos, según los cuales se llevó a cabo el entrenamiento posterior. Estas son algunas de las opciones que utilicé: Cantidad de caracteres Cantidad de palabras Longitud media de las palabras Cantidad de frases Longitud media de las frases Cantidad de palabras únicas Cantidad de palabras vacías (stop words) Ratio de palabras únicas Cantidad de signos de puntuación Ratio de signos de puntuación Cantidad de preguntas Cantidad de exclamaciones Cantidad de dígitos Cantidad de letras en mayúscula Cantidad de palabras repetidas Cantidad de bigramas únicos Cantidad de trigramas únicos Cantidad de cuatrigramas únicos Como resultado, obtuve una sencilla aplicación que podéis usar para vuestras tareas o para pasarlo bien. Así es como se ve: Para probar la aplicación podéis usar la demo online o ejecutarla en local con vuestra cuenta Cloud SQL. Todos los comentarios sobre la app son bienvenidos!
Anuncio
Esther Sanchez · 25 mar, 2021

Descripción de las Insignias de Global Masters

¡Hola Comunidad! En esta publicación, os explicamos las distintas Insignias de Global Masters y qué hay que hacer para conseguirlas. Información general sobre Niveles e Insignias de Global Masters Todos los miembros de Global Masters empiezan en el 1er nivel ("Insider"), cuando se registran en el Programa de Fidelización. Para subir de nivel, hay que ganar un número de insignias del siguiente nivel. Las insignias se ganan realizando diferentes "retos".¿Cómo puedes saber en qué nivel estás y las insignias que tienes? Sigue estos sencillos pasos: 1. En la página de inicio de Global Masters, haz clic en la foto de tu perfil, en la parte superior derecha > después, haz clic en tu nombre2. Ahí ya puedes ver en qué nivel estás, las insignias que has ganado y lo que te falta para pasar al siguiente nivel3. Si haces clic en "See available badges" verás todas las insignias y niveles del programa También puedes ver tus insignias ganadas en tu página de perfil en la Comunidad de Desarrolladores. Cómo conseguir las insignias en GM Nombre de la insignia Reglas Insignias por número de vistas Popular Writer - 750 vistas Insignias conseguidas si cualquiera de tus publicaciones (preguntas o artículos) en la Comunidad de Desarrolladores consiguen más de 750 / 2 000 / 5 000 vistas únicas. La publicación no debe ser eliminada; tiene que ser publicada. Solo cuentan las publicaciones con una calificación positiva. No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Cada insignia solo se concede una vez. Los puntos se dan por cada publicación que consigue el número de vistas indicadas. Notable Writer - 2 000 vistas Famous Writer - 5 000 vistas Gold Writer - 15 000 vistas Insignias por artículos publicados Reporter - 5 artículos Insignias conseguidas cuando llegas a 5 / 10 / 25 / 50 artículos (no preguntas) publicados en la Comunidad. Las publicaciones no deben ser eliminadas; tienen que ser publicadas. Solo cuentan las publicaciones con una calificación positiva. No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Blogger - 10 artículos Influencer - 25 artículos Opinion Maker - 50 artículos DC Best Practices Author Badge - 1 best practice Insignias conseguidas cuando llegas a 1 / 10 / 25 / 50 artículos (no preguntas) considerados como Best Practice ("Mejores prácticas") en la Comunidad de Desarrolladores. Las publicaciones no deben ser eliminadas; tienen que ser publicadas. Solo cuentan las publicaciones con una calificación positiva. No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores. RecognizableBest Practices Author Badge - 2 best practices Bronze Best Practices Author Badge - 3 best practices Silver Best Practices Author Badge- 4 best practices Gold Best Practices Author Badge - 5 best practices Master of Answers - 5 respuestas aceptadas Insignias conseguidas cuando tus respuestas en la Comunidad de Desarrolladores son marcadas 5 / 10 / 25 / 50 veces como respuestas aceptadas. Bronze Master of Answers - 10 respuestas aceptadas Silver Master of Answers - 25 respuestas aceptadas Gold Master of Answers - 50 respuestas aceptadas Insignias por preguntas Curious Member - 5 preguntas Insignias conseguidas cuando llegas a 5 / 10 / 25 / 50 preguntas en la Comunidad de Desarrolladores. Las preguntas no deben ser eliminadas; tienen que ser publicadas. Solo cuentan las preguntas con una calificación positiva. No cuentan las preguntas con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Thorough Member - 10 preguntas​ Inquisitive Member - 25 preguntas​ Socratic Member - 50 preguntas​ Insignias por favoritos Favorite Post - 10 veces Insignias conseguidas cuando tus publicaciones (preguntas o artículos) en la Comunidad de Desarrolladores, son marcadas 10 / 50 / 100 veces como favoritas. Las publicaciones no deben ser eliminadas; tienen que ser publicadas. Solo cuentan las publicaciones con una calificación positiva. No cuentan las preguntas con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Remarkable Post - 50 veces Unforgettable Post - 100 veces Insignias por votos Insightful Author - 50 votos Insignias conseguidas cuando tus publicaciones (preguntas o artículos) en la Comunidad de Desarrolladores, consiguen 50 / 100 / 500 / 1 000 votos. Las publicaciones no deben ser eliminadas; tienen que ser publicadas. No cuentan las publicaciones con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Expert Author - 100 votos Recognizable Author - 500 votos Powerful Author - 1000 votos Insightful Commenter - 50 votos Insignias conseguidas cuando tus respuestas (comentarios a preguntas) en la Comunidad de Desarrolladores, consiguen 50 / 100 / 500 / 1 000 votos. No cuentan las respuestas eliminadas No cuentan las respuestas con la etiqueta Feedback sobre la Comunidad de Desarrolladores . Expert Commenter - 100 votos Recognizable Commenter - 500 votos Powerful Commenter - 1 000 votos DC Moderator Concedida a los Moderadores de la Comunidad de Desarrolladores. Esta insignia no está relacionada con los niveles. Insignias anuales - Top 10 Autores Gold Best-Selling Author - 1er puesto 1º / 2º / 3º / 4º-10º puestos en la categoría "DC Best-Selling Author". Autores cuyos artículos consiguieron el mayor número de visualizaciones en la Comunidad de Desarrolladores durante un año. Silver Best-Selling Author - 2º puesto Bronze Best-Selling Author - 3er puesto DC Best-Selling Author - 4º-10º puestos Gold Expert - 1er puesto 1º / 2º/ 3º / 4º-10º puestos en la categoría “DC Expert”. Autores que consiguieron el mayor número de "Respuestas aceptadas" en la Comunidad de Desarrolladores durante un año. Silver Expert - 2º puesto Bronze Expert - 3er puesto DC Expert - 4º-10º puestos Gold Opinion Leader - 1er puesto 1º / 2º/ 3º / 4º-10º puestos en la categoría “DC Opinion Leader”. Autores cuyas publicaciones y respuestas obtuvieron el mayor número de votos en la Comunidad de Desarrolladores durante un año. Silver Opinion Leader - 2º puesto Bronze Opinion Leader - 3er puesto DC Opinion Leader - 4º-10º puestos Insignias por recomendaciones Gold Recruiter - 100 recomendaciones Insignias conseguidas cuando se unen a la Comunidad de Desarrolladores 1 /10 / 50 / 100 personas a las que recomendaste la Comunidad. Silver Recruiter - 50 recomendaciones Bronze Recruiter - 10 recomendaciones DC Recruiter - 1 recomendación Insignias por Contribuciones Básicas DC Author Insignia conseguida cuando publicas tu primer artículo en la Comunidad de Desarrolladores. La publicación no debe ser eliminada; tiene que ser publicada. No cuentan los artículos con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Debe ser una publicación del tipo "Artículo". InterSystems Researcher Insignia conseguida cuando publicas tu primera pregunta en la Comunidad de Desarrolladores. La pregunta no debe ser eliminada; tiene que ser publicada. No cuentan las preguntas con la etiqueta Feedback sobre la Comunidad de Desarrolladores. Debe ser una publicación del tipo "Pregunta". DC Commenter Insignia conseguida cuando publicas tu primer comentario en la Comunidad de Desarrolladores. Comentario con algún "Me gusta" o sin ningún "Me gusta" No cuentan los comentarios realizados con la etiqueta Feedback sobre la Comunidad de Desarrolladores. DC Problem Solver Insignia conseguida cuando tu respuesta a la pregunta de alguien es marcada como "Respuesta aceptada" en la Comunidad de Desarrolladores. La respuesta tiene que ser marcada como "Respuesta aceptada" No cuentan las respuestas realizadas con la etiqueta Feedback sobre la Comunidad de Desarrolladores. DC Translator Insignia conseguida cuando publicas tu primera traducción en la Comunidad de Desarrolladores. Cómo añadir una traducción Winner of Advent of Code Insignia concedida a los ganadores del concurso "Advent of Code". Mas info aquí. Global Master of the Month Insignia concedida a los "Advocate of the Month" en Global Masters. Gold Advocate of the Year Insignias concedidas a los "Best Advocates of the Year" en Global Masters. Silver Advocate of the Year Bronze Advocate of the Year Insignias de Open Exchange InterSystems Open Exchange Developer Insignias conseguidas cuando publicas 1 / 5 / 10 / 25 aplicaciones en InterSystems Open Exchange. Bronze Open Exchange Developer Silver Open Exchange Developer Gold Open Exchange Developer Además... Consulta la información adicional sobre Global Masters: Cómo unirse a Global Masters Descripción de los Niveles de Global Masters Si tienes alguna duda sobre las Insignias, puedes dejarnos un comentario en esta publicación y te responderemos al momento!
Artículo
Alberto Fuentes · 17 abr, 2019

Publicador-Subscriptor simple con $system.Event

El archivo events_examples.zip contiene dos ejemplos que muestran cómo procesar una carga de trabajo de forma asíncrona utilizando colas persistentes.Events_Simple.prj.xmlEvents_PubSub.prj.xml (actualizado! este ejemplo se ha publicado en https://github.com/intersystems-ib/cache-iat-pubsub)Events SimpleEste es un ejemplo muy sencillo que crea algunos procesos trabajadores y les encola mensajes utilizando $system.Event. ; crear un recurso compartido y crear los procesos trabajadores USER>do ##class(IAT.S04.Event.Test).Setup() ; encolar algunos mensajes hacia los trabajadores y ver qué sucede USER>do ##class(IAT.S04.Event.Test).Run() Show log? no/[yes]: ^Samples.Log=10 ^Samples.Log(1)="[2016-02-19 09:43:14] Enqueuing 1" ^Samples.Log(2)="[2016-02-19 09:43:14] Worker 8168 grabs: 1" ^Samples.Log(3)="[2016-02-19 09:43:14] Enqueuing 2" ^Samples.Log(4)="[2016-02-19 09:43:14] Worker 18184 grabs: 2" ^Samples.Log(5)="[2016-02-19 09:43:14] Enqueuing 3" ^Samples.Log(6)="[2016-02-19 09:43:14] Worker 8168 grabs: 3" ^Samples.Log(7)="[2016-02-19 09:43:14] Enqueuing 4" ^Samples.Log(8)="[2016-02-19 09:43:14] Worker 18184 grabs: 4" ^Samples.Log(9)="[2016-02-19 09:43:14] Enqueuing 5" ^Samples.Log(10)="[2016-02-19 09:43:14] Worker 8168 grabs: 5" ; trabajo terminado, podemos enviar más mensajes o matar a los procesos trabajadores write $system.Process.Terminate(8168) 1 write $system.Process.Terminate(18184) 1 Clases: Manager - métodos para crear recursos compartidos así como los procesos trabajadores y encolar mensajes.Queue - clase persistente simple utilizada para almacenar mensajes.Worker - representa a un trabajador que espera que le llegue un evento para procesar el mensaje recibido. Events PubSub Este ejemplo está construido sobre la misma base que Events_Simple. El objetivo en este caso es construir un modelo sencillo de Publicador-Subscriptor. Hay dos subscriptores para dos tipos de mensajes distintos: SubPatient - gestiona los mensajes relacionados con pacientes.SubDummy - gestiona mensajes dummys. ; crear los eventos y los procesos subscriptores do ##class(IAT.S05.PubSub.Example.Main).Setup() ; enviar algunos mensajes (de los dos tipos) al canal do ##class(IAT.S05.PubSub.Example.Main).Run() ; mostrar el log con el resultado de lo que ha sucedido zw ^PubSub.Log Log Clases Hola Alberto!¡Qué buen artículo!Puedes a publicar el ejemplo en Open Exhcange tambien?
Artículo
Kurro Lopez · 20 abr, 2020

Enviar un correo electrónico HTML con una imagen

Aqui teneis una clase "test" con el código para envíar un correo electrónico en formato HTML con una imagen incrustada. Edita el texto para cambiar la imagen incrustada, dirección de destino y remitente, asunto, contenido, etc... Class objectscript.sendEmailWithImage Extends %RegisteredObject { classmethod test() { S SmtpServer = "" S SmtpUserName = "" S SmtpPassword = "" S imgPath="C:\test.jpg" set s=##class(%Net.SMTP).%New() set s.smtpserver=SmtpServer set auth=##class(%Net.Authenticator).%New() ; use default authentication list set auth.UserName=SmtpUserName set auth.Password=SmtpPassword set s.authenticator=auth Set objMail=##class(%Net.MailMessage).%New() Set objMail.From="sender@testhost.com" Do objMail.To.Insert("reciever@testhost.com") Set objMail.Subject="Test-Email" Set objMail.Charset="iso-8859-1" Set obj1 =objMail Set obj1.IsHTML=1 Set obj1.IsBinary = 0 Set obj1.IsMultiPart = 1 Set obj1.MultiPartType ="related" Do obj1.Headers.SetAt("inline","Content-Disposition") //alternative container for the text-parts #dim textbody as %Net.MailMessagePart s textbody = obj1.AttachNewMessage() s textbody.IsMultiPart=1 s textbody.IsHTML=0 s textbody.MultiPartType="alternative" //html part #dim text as %Net.MailMessagePart //text part #dim texttxt as %Net.MailMessagePart s texttxt = textbody.AttachNewMessage() //s texttxt.ContentType="text/plain" d texttxt.TextData.Write("this is plain text") s text = textbody.AttachNewMessage() s text.IsHTML=1 s text.IsBinary=0 s text.IsMultiPart=0 Do text.TextData.Write("<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN"">") do text.TextData.Write("<html><head><meta http-equiv=""content-type"" content=""text/html; charset=ISO-8859-1"">") Do text.TextData.Write("</head><body text=""#000000"" bgcolor=""#ffffff"">") Do text.TextData.Write("Das ist ein Test in html") Do text.TextData.Write("<img src=""cid:test.jpg"" />") Do text.TextData.Write("</body></html>") // Image Message Part #dim obj2 as %Net.MailMessagePart Set obj2 = obj1.AttachNewMessage() Set obj2.IsBinary = 1 Set obj2.IsMultiPart = 0 Set obj2.FileName="test.jpg" Do obj2.BinaryData.LinkToFile(imgPath) Do obj2.Headers.SetAt("inline","Content-Disposition") Do obj2.Headers.SetAt("<test.jpg>","Content-ID") set status=s.Send(objMail) d $system.OBJ.DisplayError(status) w status,! } } Aquí tienes el enlace para ver el código en GitHub: https://github.com/intersystems-community/code-snippets/blob/master/src/cls/objectscript/sendEmailWithImage.cls
Artículo
Alberto Fuentes · 8 jun, 2021

Trucos y consejos de VSCode - Asistente SOAP

Otro artículo sobre "Trucos y consejos de VSCode" - ![](/sites/default/files/inline/images/images/image(1524).png) ¿Quieres ver esta opción en VSCode? Esta vez nos centraremos en cómo obtener el Asistente SOAP (*SOAP Wizard*) tal y como estaba disponible en Studio — para definir un cliente de servicio web SOAP basado en WSDL (y *Business Operation*), o servicio —. Si trabajas con Servicios web (*Web services*), lo más probable es que hayas utilizado el Asistente SOAP en Studio. Lo abrirías en *Tools > Add-Ins*: ![](/sites/default/files/inline/images/images/image(1520).png) Y este abría una "*Server Template*": ![](/sites/default/files/inline/images/images/image(1521).png) En VSCode, puede que te preguntes cómo puedes acceder a eso. Bueno, el hecho básico que hay que comprender es que realmente este complemento o asistente es simplemente una página web, que se muestra en Studio como hemos visto anteriormente y, como tal, también se puede acceder a ella desde un simple navegador. VSCode facilita la apertura de dicho navegador con el contenido deseado (construyendo la URL correcta con el nombre del servidor, el puerto, la aplicación web, etc.). El resultado sería el mismo que ver una opción para abrir el Portal de administración o la Referencia de clase (con las URLs correspondientes) al hacer clic en la Conexión del servidor sobre la barra de estado inferior de VSCode, por ejemplo: ![](/sites/default/files/inline/images/images/image(1522).png) También verás una entrada para el Asistente SOAP. Puedes conseguir esto al añadir una entrada 'links' a tu objeto 'conn' que se encuentra en tu configuración de JSON de tu extensión ObjectScript, y especificando la URL deseada (utilizando las variables correspondientes). Esto se mencionó en un debate sobre Problemas con VSCode que se encuentra en el GitHub VSCode ObjectScript, como [problema "Asistente SOAP"](https://github.com/intersystems-community/vscode-objectscript/issues/325), con comentarios de @John Murray y @Ondřej Hoferek, y también se menciona en esta respuesta de @Timothy Leavitt a una pregunta de la Comunidad.   El valor JSON sería: "SOAP Wizard": "${serverUrl}/isc/studio/templates/%25ZEN.Template.AddInWizard.SOAPWizard.cls?Namespace=${namespace}${serverAuth}" Y esta parte se vería así: ![](/sites/default/files/inline/images/images/image(1526).png) Una vez que tengas esto, verás una opción adicional cuando hagas clic en la Conexión - ![](/sites/default/files/inline/images/images/image(1524).png) Y al elegir esa opción accederás al esperado asistente (abierto en un navegador): ![](/sites/default/files/inline/images/images/image(1525).png) Os dejo un breve GIF mostrando este proceso (comienza por el menú normal al hacer clic en la Conexión, y termina con el menú que incluye el Asistente SOAP). ![](/sites/default/files/inline/images/vscodesoapwizardvideo.gif)   Fíjate que hay otros asistentes (o plantillas) que puedes añadir de esta manera (como el Asistente XSD, por ejemplo).   Excelente consejo, tanto para abrir este wizard como el resto de asistentes, poco a poco el VSCode va cogiendo forma. ¡Muchas gracias Alberto! Hay que potenciar el VSCode.
Artículo
Eduardo Anglada · 25 mayo, 2021

Cómo crear y registrar definiciones XData

¡Hola Comunidad! ObjectScript, el lenguaje de InterSystems IRIS, tiene la capacidad de extender clases utilizando una funcionalidad muy interesante llamada XData. Es una sección en tu clase que puede ser usada para crear definiciones personalizadas, para utilizarlas dentro de la clase misma o externamente. Crear una o más definiciones XData para tu clase es muy sencillo, mira el ejemplo: Class dc.Sample.Person Extends (%Persistent, %JSON.Adaptor, %Populate) { Property Name As %VarString; Property Title As %String; Property Company As %String; Property Phone As %VarString; Property DOB As %Date(MAXVAL = "$piece($horolog, "","", 1)"); /// Index for property DOB Index DOBIndex On DOB; ClassMethod AddTestData(amount As %Integer = 10) { d ..Populate(amount) } /// Documentation for Person XData PersonDocHtml [ MimeType = text/html ] { <h1>This is the Person class</h1> } XData PersonDocMarkdown [ MimeType = text/markdown ] { <h1>This is the Person class</h1> } Ten en cuenta que tras definir los métodos, solo tienes que añadir una o más secciones XData con tres subsecciones: XData NomeSecaoXData [MimeType = TypeOfMimeType]. El contenido se pone entre corchetes. Todos los elementos XData se almacenan en la clase persistente % Dictionary.XDataDefinition. Esto significa que es posible recuperar las definiciones usando lenguaje SQL, internamente o externamente. Mira el ejemplo: Class dc.mkdocs.Generator { ClassMethod Generate() { Set qry = "SELECT parent, Name, Description FROM %Dictionary.XDataDefinition WHERE MimeType IN ('text/markdown','text/html')" Set stm = ##class(%SQL.Statement).%New() Set qStatus = stm.%Prepare(qry) If qStatus'=1 {Write "%Prepare failed:" Do $System.Status.DisplayError(qStatus) Quit} Set rset = stm.%Execute() While rset.%Next() { Write "Row count ",rset.%ROWCOUNT,! Write rset.parent Write ": ",rset.Description,! Write ..GetXDataContent(rset.parent,rset.Name),!! } Write !,"Total row count=",rset.%ROWCOUNT } ClassMethod GetXDataContent(className, xdataName) As %String { set content = "" for i=1:1:$$$comMemberKeyGet(className,$$$cCLASSxdata,xdataName,$$$cXDATAdata) { set content = content_$$$comMemberArrayGet(className,$$$cCLASSxdata,xdataName,$$$cXDATAdata,i) } quit content } } En este ejemplo, todos los elementos XData con Mime Type markdown y html son recuperados y se imprime tanto el nombre de la clase en la que se localiza el elemento XData como su descripción. Si quieres recuperar el contenido del elemento XData consulta GetXDataContent (gracias @Eduard.Lebedyuk). Es una funcionalidad muy interesante, ya que podemos catalogar la documentación de todas las clases de una aplicación y tener un fácil acceso a ellas. ¡Genial!
Anuncio
Ricardo Paiva · 18 mar, 2022

HL7v2 a FHIR, ¡es fácil!

# Iris Healthtoolkit Service [![Video](https://raw.githubusercontent.com/grongierisc/iris-healthtoolkit-service/main/misc/images/Cover.png)](https://youtu.be/lr2B7zSFkds "Video") Fácil de usar HL7v2 a FHIR, CDA a FHIR, FHIR a HL7v2 como un Servicio. El objetivo de este proyecto es ofrecer una API REST que pueda convertir fácilmente varios formatos de salud. Publica el formato deseado en el cuerpo REST, obtén la respuesta en el nuevo formato. * ![emoji](https://community.intersystems.com/sites/all/libraries/ckeditor/plugins/smiley/images/tongue_smile.png) SaaS Offer : https://aws.amazon.com/marketplace/pp/prodview-q7ryewpz75cq2 ![emoji](https://community.intersystems.com/sites/all/libraries/ckeditor/plugins/smiley/images/tongue_smile.png) * ![emoji](https://community.intersystems.com/sites/all/libraries/ckeditor/plugins/smiley/images/devil_smile.png) Video : https://youtu.be/lr2B7zSFkds ![emoji](https://community.intersystems.com/sites/all/libraries/ckeditor/plugins/smiley/images/devil_smile.png) ## Instalación Clona este repositorio ``` git clone https://github.com/grongierisc/iris-healthtoolkit-service.git ``` Docker ``` docker-compose up --build -d ``` ## Uso * Ve a: http://localhost:32783/swagger-ui/index.html ## Detalles de la API * HL7 a FHIR ``` POST http://localhost:32783/api/hl7/fhir ``` * FHIR a HL7 ADT ``` POST http://localhost:32783/api/fhir/hl7/adt ``` * FHIR a HL7 ORU ``` POST http://localhost:32783/api/fhir/hl7/oru ``` * FHIR a HL7 vxu ``` POST http://localhost:32783/api/fhir/hl7/vxu ``` * CDA a FHIR ``` POST http://localhost:32783/api/cda/fhir ``` * FHIR repo ``` GET http://localhost:32783/api/fhir/metadata ``` ## Formatos de entrada de HL7 compatibles: * ADT_A01, ADT_A02, ADT_A03, ADT_A04, ADT_A05, ADT_A06, ADT_A07, ADT_A08, ADT_A09, ADT_A10, ADT_A11, ADT_A12, ADT_A13, ADT_A17, ADT_A18, ADT_A23, ADT_A25, ADT_A27, ADT_A28, ADT_A29, ADT_A30, ADT_A31, ADT_A34, ADT_A36, ADT_A39, ADT_A40, ADT_A41, ADT_A45, ADT_A47, ADT_A49, ADT_A50, ADT_A51, ADT_A60 * BAR_P12 * MDM_T02, MDM_T04, MDM_T08, MDM_T11 * OMP_O09 * ORM_O01 * ORU_R01 * PPR_PC1, PPR_PC2, PPR_PC3 * RDE_O11 * SIU_S12, SIU_S13, SIU_S14, SIU_S15, SIU_S16, SIU_S17, SIU_S26 * VXU_V04 ## Cómo funciona El proyecto funciona con el diagrama dinámico: SDA. El SDA (Summary Document Architecture) es el Formato de Datos Clínicos de InterSystems. Las correspondencias SDA FHIR se pueden consultar [aquí](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=HXFHIR_transforms), y las de CDA -> SDA [aquí](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI.Page.cls?KEY=HXCDA). ![gif sda pivot](https://raw.githubusercontent.com/grongierisc/iris-healthtoolkit-service/main/misc/images/Gif_SDA_Pivot.gif)
Artículo
Ricardo Paiva · 29 ene, 2021

Cómo leer los datos de AWS S3 sobre el COVID como tablas SQL en IRIS

¡Hola Desarroladores! IRIS External Table es un proyecto de código abierto de la comunidad de InterSystems, que permite utilizar archivos almacenados en el sistema de archivos local y almacenar objetos en la nube como AWS S3 y tablas SQL. ![IRIS External Table](https://github.com/intersystems-community/IRIS-ExternalTable/raw/master/images/ExternalTableDiagram.png) Se puede encontrar en GitHub Open Exchange y está incluido en el administrador de paquetes InterSystems Package Manager (ZPM). Para instalar External Table desde GitHub, utilice: git clone https://github.com/antonum/IRIS-ExternalTable.git iris session iris USER>set sc = ##class(%SYSTEM.OBJ).LoadDir("/IRIS-ExternalTable/src", "ck",,1) Para instalarlo con el ZPM Package Manager, utilice: USER>zpm "install external-table" ## Cómo trabajar con archivos locales Crearemos un archivo simple que tiene este aspecto: a1,b1 a2,b2 Abra su editor favorito y cree el archivo o utilice solo una línea de comandos en Linux/Mac: echo $'a1,b1\na2,b2' > /tmp/test.txt Cree una tabla SQL en IRIS para representar este archivo: create table test (col1 char(10),col2 char(10)) Convierta la tabla para utilizar el almacenamiento externo: CALL EXT.ConvertToExternal( 'test', '{ "adapter":"EXT.LocalFile", "location":"/tmp/test.txt", "delimiter": "," }') Y finalmente, consulte la tabla: select * from test Si todo funciona según lo previsto, debería ver el resultado de la siguiente forma: col1 col2 a1 b1 a2 b2 Ahora regrese al editor, modifique el contenido del archivo y ejecute nuevamente la consulta SQL. ¡¡¡Tarán!!! Está leyendo nuevos valores de su archivo local en SQL. col1 col2 a1 b1 a2 b99 ## Cómo leer los datos desde S3 En puede acceder a los datos de la COVID que se actualizan constantemente, estos se almacenan por AWS en el lago de datos públicos. Intentaremos acceder a una de las fuentes de datos en este lago de datos: `s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states` Si tiene instalada la herramienta de línea de comandos para AWS, puede repetir los siguientes pasos. Si no es así, vaya directamente a la parte de SQL. No es necesario que tenga ningún componente específico de AWS instalado en su equipo para continuar con la parte de SQL. $ aws s3 ls s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/ 2020-12-04 17:19:10 510572 us-states.csv $ aws s3 cp s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv . download: s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv to ./us-states.csv $ head us-states.csv date,state,fips,cases,deaths 2020-01-21,Washington,53,1,0 2020-01-22,Washington,53,1,0 2020-01-23,Washington,53,1,0 2020-01-24,Illinois,17,1,0 2020-01-24,Washington,53,1,0 2020-01-25,California,06,1,0 2020-01-25,Illinois,17,1,0 2020-01-25,Washington,53,1,0 2020-01-26,Arizona,04,1,0 Por lo tanto, tenemos un archivo con una estructura bastante simple y cinco campos delimitados. Para mostrar esta carpeta S3 como en External Table, primero necesitamos crear una tabla “regular” con la estructura deseada: -- create external table create table covid_by_state ( "date" DATE, "state" VARCHAR(20), fips INT, cases INT, deaths INT ) Tenga en cuenta que algunos campos de datos como “Date” son palabras reservadas en el SQL de IRIS y deben escribirse entre comillas dobles. Entonces, necesitamos convertir esta tabla “regular” en la tabla “externa”, basada en el bucket AWS S3 y con el tipo CSV. -- convert table to external storage call EXT.ConvertToExternal( 'covid_by_state', '{ "adapter":"EXT.AWSS3", "location":"s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/", "type": "csv", "delimiter": ",", "skipHeaders": 1 }' ) Si observa detenidamente, en EXT.ExternalTable los argumentos de los procedimientos son el nombre de la tabla y luego la cadena JSON, además contiene varios parámetros como la ubicación para buscar archivos, el adaptador para utilizarlos, un delimitador, etc. Además, External Table de AWS S3 es compatible con el almacenamiento de Azure BLOB, Google Cloud Buckets y el sistema de archivos local. El repositorio de GitHub contiene referencias para la sintaxis y opciones que son compatibles con todos los formatos. Y finalmente, consulte la tabla: -- query the table select top 10 * from covid_by_state order by "date" desc [SQL]USER>>select top 10 * from covid_by_state order by "date" desc 2. select top 10 * from covid_by_state order by "date" desc date state fips cases deaths 2020-12-06 Alabama 01 269877 3889 2020-12-06 Alaska 02 36847 136 2020-12-06 Arizona 04 364276 6950 2020-12-06 Arkansas 05 170924 2660 2020-12-06 California 06 1371940 19937 2020-12-06 Colorado 08 262460 3437 2020-12-06 Connecticut 09 127715 5146 2020-12-06 Delaware 10 39912 793 2020-12-06 District of Columbia 11 23136 697 2020-12-06 Florida 12 1058066 19176 Es comprensible que se necesite más tiempo para consultar los datos de la tabla remota, que para consultar la tabla “nativa de IRIS” o la tabla basada en el global, pero esta se almacena y actualiza completamente en la nube, y en segundo plano se extrae a IRIS. Exploremos un par de funciones adicionales de External Table. ## %PATH y las tablas basadas en varios archivos La carpeta de nuestro ejemplo, que se encuentra en el bucket, contiene solo un archivo. Lo más común es que tenga varios archivos de la misma estructura, donde el nombre del archivo identifique tanto al registro de la hora como al identificador de algún otro atributo que queramos utilizar en nuestras consultas. El campo %PATH se agrega automáticamente a cada tabla externa y contiene la ruta completa hacia el archivo de donde se recuperó la fila. select top 5 %PATH,* from covid_by_state %PATH date state fips cases deaths s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-21 Washington 53 1 0 s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-22 Washington 53 1 0 s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-23 Washington 53 1 0 s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-24 Illinois 17 1 0 s3://covid19-lake/rearc-covid-19-nyt-data-in-usa/csv/us-states/us-states.csv 2020-01-24 Washington 53 1 0 Puede utilizar el campo %PATH en sus consultas SQL como cualquier otro campo. ## De datos ETL a “tablas regulares” Si su tarea es cargar datos de S3 en una tabla IRIS, puede utilizar External Table como una herramienta ETL. Simplemente haga lo siguiente: INSERT INTO internal_table SELECT * FROM external_table En nuestro caso, si queremos copiar los datos COVID de S3 a la tabla local: --create local table create table covid_by_state_local ( "date" DATE, "state" VARCHAR(100), fips INT, cases INT, deaths INT ) --ETL from External to Local table INSERT INTO covid_by_state_local SELECT TO_DATE("date",'YYYY-MM-DD'),state,fips,cases,deaths FROM covid_by_state ## UNIÓN entre IRIS, tablas nativas y externas. Consultas federadas External Table es una tabla SQL. Se puede unir con otras tablas, utilizarse en subconsultas y sistemas de archivos tipo UNION. Incluso puede combinar la tabla “Regular” de IRIS y dos o más tablas externas que provengan de diferentes fuentes en la misma consulta SQL. Intente crear una tabla regular, por ejemplo, haga coincidir los nombres de los estados con sus códigos como en el caso de Washington y WA. Y únalos con nuestra tabla basada en S3. create table state_codes (name varchar(100), code char(2)) insert into state_codes values ('Washington','WA') insert into state_codes values ('Illinois','IL') select top 10 "date", state, code, cases from covid_by_state join state_codes on state=name Cambie “join” por “left join” para incluir aquellas filas donde el código del estado no esté definido. Como puede ver, el resultado es una combinación de datos provenientes de S3 y su tabla nativa de IRIS. ## Acceso seguro a la información El lago de datos Covid en AWS es público. Cualquier persona puede leer los datos que provengan de esta fuente sin la necesidad de tener alguna autenticación o autorización. En la vida real seguramente quiere acceder a sus datos de una forma segura, donde se evite que extraños echen un vistazo a sus archivos. Los detalles completos sobre AWS Identity y Access Management (IAM) están fuera del alcance de este artículo. Pero lo mínimo que debe saber es que necesita por lo menos la clave de acceso a la cuenta y la información confidencial de AWS para acceder a los datos privados de su cuenta. AWS utiliza la autenticación de claves/información confidencial de la cuenta para firmar las solicitudes. https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys Si está ejecutando IRIS External Table en una instancia de EC2, la forma recomendada de lidiar con la autenticación es utilizando las funciones que se encuentran en la instancia de EC2 https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html. De este modo, IRIS External Table podría utilizar los permisos de esa función. No se requiere ninguna configuración adicional. En una instancia local o que no sea de EC2 es necesario especificar AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY, ya sea con la ayuda de variables de entorno o mediante la instalación y configuración del cliente CLI de AWS. export AWS_ACCESS_KEY_ID=AKIAEXAMPLEKEY export AWS_SECRET_ACCESS_KEY=111222333abcdefghigklmnopqrst Asegúrese de que la variable de entorno sea visible dentro del proceso de IRIS. Puede verificarlo al ejecutar: USER>write $system.Util.GetEnviron("AWS_ACCESS_KEY_ID") Esto debería emitir el valor de la clave. O instale el CLI de AWS, mediante instrucciones que se encuentran aquí: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html y ejecutar: aws configure Entonces External Table podrá leer las credenciales desde los archivos de configuración para el CLI de AWS. Posiblemente su shell interactivo y el proceso de IRIS estén ejecutándose en cuentas diferentes, asegúrese de ejecutar `aws configure` con la misma cuenta que su proceso de IRIS. Este artículo ha sido etiquetado como "Mejores prácticas" ("Best practices"). Los artículos con la etiqueta "Mejores prácticas" incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems.
Artículo
Heloisa Paiva · 1 jun, 2023

Memoria ocupada por las tablas de IRIS

Introducción Entre las diversas soluciones que desarrollamos en Innovatium, un desafío habitual es la necesidad de acceder al tamaño de las bases de datos. Entonces me di cuenta de que eso no es algo tan trivial en IRIS. Ese tipo de información es importante para mantener un control del flujo de datos y del coste en gigabytes de un sistema para implementar. Sin embargo, lo que realmente me llamó la atención fue la necesidad de eso para algo muy importante: la migración a la nube. Al final, ¿quién no quiere migrar sus sistemas a la nube hoy en día? Los servicios cloud ofrecen, de manera sencilla, todo lo que un sistema necesita: mirroring, escalabilidad, protección de datos, facilidad de flujo y lo que hace que todas las empresas se enamoren: solo se paga por lo que se usa. Y además, con los gigantes Google (Cloud), Microsoft (Azure), Amazon (AWS), etc. ofreciendo sus servicios casi impecables a precios accesibles, es algo que con una pequeña inversión puede ser una realidad para cualquiera que quiera aumentar sus ganancias y ahorrar a largo plazo. Además, para aquellos que ya están aquí, InterSystems también tiene sus propios servicios en la nube. Por eso os voy a presentar la aplicación que estoy desarrollando, en la cual no solo es posible, sino también es fácil, observar el tamaño de los globals, para que los análisis necesarios para obtener un servicio cloud sean tan complicado como tu proveedor favorito lo complique. Inspiración Inspirándome en las aplicaciones isc-global-size-tracing y globals-tool, estoy creando una versión que pueda unir lo mejor de cada una y añadir las adaptaciones necesarias para nuestro negocio. Pero antes de mostrar mi desarrollo, voy a presentar brevemente las aplicaciones comentadas. isc-global-size-tracing ofrece servicios de análisis a partir de clases dentro de IRIS, con métodos más amigables para el usuario y opciones de tareas programadas que actualizan una tabla con varios datos sobre los globals. Hay también opciones predefinidas para exportar las información a archivos externos. Así, si ya hay conocimiento de ObjectScript no es tan difícil dedicar unos minutos a entender cómo funciona y adaptarlo a tu negocio. Globals-tool muestra un portal en forma de página web, donde es posible verificar los tamaños asignados y los tamaños disponibles para cada global, dentro de sus namespaces. Es un poco más simple, pero más amigable para el usuario, y también se puede utilizar para compartir los datos con personas de otras áreas sin conocimientos de programación. Los cambios y adaptaciones pueden requerir conocimientos previos no solo de ObjectScript, sino también de React y similares. Lo que me gustaría entonces es combinar las diversas opciones de la primera con la facilidad de uso de la segunda, además de añadir otras funciones de análisis y exportación. La aplicación - lo que ya está disponible En esta sección, voy a explicar un poco lo que ya está hecho y cómo puedes aprovecharlo tú y tu empresa. Todo el código está disponible para consultar, clonar o descargar en mi Github. Empezar a utilizarla es muy sencillo, solamente hay que clonar o descargar el repositorio en la carpeta que prefieras y configurar para tu instancia de IRIS. Abre el terminal en la carpeta donde quieres clonar el repositorio y usa el comando git clone https://github.com/heloisatambara/iris-size-django Entra en la carpeta iris-size-django e instala los requisitos necesarios: .../iris-size-django > pip install -r requirements.txt Edita el archivo .../iris-size-django/globalsize/settings.py para personalizar la configuración de la base de datos. No cambies el parámetro ENGINE, debe apuntar a la aplicación de CaretDev, django-iris. Sin embargo, hay que cambiar NAME para el namespace, USER y PASSWORD para un usuario con los privilegios adecuados (se requiere acceso al namespace %SYS y poder crear una tabla en el namespace deseado) y los parámetros HOST y PORT deben apuntar a tu instancia. De vuelta al terminal, vamos a ejecutar los comandos makemigrations para preparar la aplicación, migrate para crear la tabla donde vamos a almacenar la información de los globals y runserver para poner todo en práctica. > python manage.py makemigrations > python manage.py migrate > python manage.py runserver Ahora, simplemente abre el enlace http://127.0.0.1:8000/globals/ en un navegador y haz clic en Update. En pocos segundos deberías ver una tabla con todos los namespaces y sus respectivos globals, mostrando la cantidad (en megabytes) de memoria asignada y utilizada, como se ve en la imagen al inicio de esta sección. Ahora vamos a analizar mejor la parte superior de la foto: Aquí se pueden ver las opciones de filtros, exportación y ordenación. Puedes escribir parte del nombre de la base de datos o de los globals para ver resultados específicos, o escribir un número positivo en Size o Allocated para ver resultados por encima de ese valor. Si escribes un número negativo, tendrás los resultados debajo del módulo del valor. Haz clic en Filter para aplicar el filtro. Selecciona el modelo de exportación (CSV, XML, JSON) y haz clic en Export para exportar a la carpeta iris-size-django. Ten en cuenta que los filtros aplicados se reflejarán en la exportación. Además, puedes cambiar la dirección de exportación en el código, en .../iris-size-django/globals/views.py.> Finalmente, puedes seleccionar el orden ascendente en orden alfabético, por el nombre de la base de datos y del global o por el espacio ocupado o por la cantidad asignada. Haz clic en Filter para efectuar la ordenación y los filtros aplicados. Nota: la ordenación no se reflejará en la exportación. Al final de la página se puede ver el recuento de globals dentro de los filtros seleccionados, además de la cantidad total asignada y utilizada: Si quieres hacer análisis más detallados o incluso ver la tabla original, una buena opción es entrar en el portal de administración de la instancia referida en settings.py, en la sesión de SQL y seleccionar el namespace referido en el mismo lugar. La tabla habrá sido creada automáticamente por Django con el nombre de SQL_User.globals_iglobal, y ahí puedes usar las herramientas de InterSystems para ejecutar todo tipo de consultas. Nota: en settings.py, el parámetro DEBUG está marcado como TRUE, porque aún está en desarrollo. Ideas futuras Mis próximas ideas son añadir más funciones al portal. Actualmente es posible modificar configuraciones de exportación y de la base de datos directamente en el código, además de realizar consultas más complejas a través del portal de IRIS. Sin embargo, creo que unificar todo eso en el portal puede ser más eficiente. Además, también estoy estudiando añadir un siguimiento del flujo de datos por período. Por fin, me gustaría saber vuestra opinión: ¿Creéis que ese tipo de aplicación puede ayudar a vuestros negocio? ¿Qué otras funciones os gustaría ver aquí? ¿Os gustaría ver alguna función ya existente de IRIS de manera más amigable? ¿O preferiríais que algo presentado aquí fuera más simple?
Artículo
Ariel Arias · 22 nov, 2022

IAM & IRIS / IRIS Health desde un mismo archivo YML

Disclosure Statement: Sugerencias para relalizar pruebas en ambientes usados para demostraciones o desarrollos, no en ambientes productivos. Caso de uso: teniendo IAM, lo ejecutamos desde un archivo YML, y necesitamos que se conecte a una Instancia IRIS en seguida, pero IRIS tiene deshabilitado el usuario IAM y la aplicación IAM. Alternativa: Modificamos el archivo YAML para agregar la imagen IRIS / IRIS for Health que queremos utilizar, nos aseguramos que usen la misma red; ya sea que la hemos definido previamente y queremos acoplar estas nuevas imágenes a esta red, o creamos una nueva para aislar estas nuevas imágenes en un ambiente propio; y lo principal: ejecutamos un script para habilitar el usuario y la aplicación IAM de modo que al iniciar quede todo el ambiente operativo. Requisito: Acceso a WRC para descarga de imagen de IAM (IRIS API Manager) Distribution page PASO A PASO Lo primero es comentar que la primera vez que quise usar el script que viene con el mismo instalador, me encontré con dos inconvenientes (para mi, es probable que quien tiene mayor conocimiento de Docker y Kubernetes no lo vea como inconveniente) y es que, por un lado, quería conectar este IAM con una instancia de IRIS que ya estaba en ejecución y con algunas API desarrolladas, entonces esperaba que fuera "ejecutar y conectar", y me percaté que: - El usuario IAM y la aplicación IAM de mi instancia están deshabilitados. - Al momento de ejecutar con "docker compose up -d", se crea una nueva red con el nombre "scripts_default", entonces si quiero que se comunique con mi instancia (otra imagen docker de IRIS en otra red llamada "irisenv-net" debo ejecutar unos pasos adicionales. Una alternativa que encontré y me llevó a escribir este artículo, es, primero crear una red en docker que será utilizada en adelante por mis imagenes docker network create -d bridge irisenv-net Y luego modificar el docker-compose.yml para utilizar una red ya creada por docker y que usan otras imagenes en ejecución, para ello, agregué al archivo lo siguiente: networks: irisenv-net: external: true Con esto, las imagenes que usen la red "irisenv-net" se comunicarán entre ellas sin pasos adicionales. Entonces para cada imagen del archivo, agregué también: networks: - irisenv-net Me quedaba pendiente lo del usuario y aplicación IAM, que al ser una instancia ya en ejecución debía ejecutar manualmente tanto la habilitación como el establecer la contraseña que usaría mi usuario IAM, pues hay que pasarle ese parámetro al script. Pero, ¿Si no está en ejecución?, ¿Puedo desde un mismo script levantar una imagen de IRIS, al mismo tiempo que levanto el IAM y que queden automáticamente conectadas y además el IAM tome la licencia existente en IRIS?: Mi respuesta fue SI. De la siguiente forma: - Agregar en un mismo archivo (docker-iris.yml por ejemplo) la llamada a la imagen de IRIS que voy a utilizar, luego las que requiere IAM y las de IAM debo hacerlas depender de IRIS, entonces es un paso de copiar y pegar y modificar para dejar todo establecido. Hasta acá tenemos un archivo que al ser ejecutado iniciará 4 imagenes: IRIS, IAM-MIGRATION, IAM y DB Entonces, ¿Cómo resolvemos que al iniciar la instancia de IRIS, además de cargar la licencia, habilite el usuario IAM con una contraseña que conozco y puedo pasarle como parámetro al IAM, y además se habilite la aplicación IAM?. Respuesta: con un script que se ejecute al momento de iniciar la imagen de IRIS, es decir, tenemos un archivo docker llamado "irisdpfile" que contiene el detalle de la imagen que usaremos y agregamos la llamada al script. El script que vamos a utilizar: zn "%SYS" Do ##class(Security.Users).UnExpireUserPasswords("*") set st=$SYSTEM.Security.ChangePassword("IAM","iampassword") set iamuser = ##class(Security.Users).%OpenId("iam") set iamuser.Enabled = 1 set iamuser.AccountNeverExpires = 1 Set st = iamuser.%Save() Set iamapp = ##class(Security.Applications).%OpenId("/api/iam") Set iamapp.Enabled = 1 Set st = iamapp.%Save() zn "USER" Si vemos el detalle, en este archivo, habilitamos los usuarios que puedan estar expirados (por ejemplo el "superuser"); luego establecemos una nueva password para el usuario IAM y finalmente habilitamos la aplicación "/api/iam". Este archivo, lo guardé en el mismo directorio desde donde estoy ejecutando el "docker-iris.yml" y lo nombré: "enableirisuser.script" De esta forma, desde el dockerfile de IRIS (irisdpfile) agregué las líneas: USER irisowner COPY ./enableirisuser.script /tmp/enableirisuser.script RUN iris start IRIS \ && iris session IRIS < /tmp/enableirisuser.script \ && iris stop IRIS quietly USER irisowner Nota: Deben quedar en una misma línea de ejecución el iniciar la instancia y llamada al script, me pasó que quise hacer todo por separado y no me dio resultado. Así, logré desde un mismo archivo, levantar una instanacia de IRIS y de IAM, donde IAM lograba comunicarse con IRIS sin problema y dejar en seguida habilitada la licencia para poder crear workspaces, ambiente de desarrolladores, y todo lo que sea necesario desde IAM. docker-compose -f docker-iris.yml up -d Les comparto cómo quedó mi archivo yml finalmente: version: "3.7" services: irishost: depends_on: - irishealth build: context: . dockerfile: irisdpfile container_name: irishost volumes: - type: bind source: ./Licencias/ target: /licencias - type: bind source: ../sharingweb/T2017/ target: /common_shared - type: bind source: ./wwwshared/ target: /wwwfiles command: --key /licencias/iris.key --check-caps false environment: IRIS_MASTER_HOST: APPTNOTSrv # DNS based on the name of the service! IRIS_MASTER_PORT: 51773 IRIS_MASTER_USERNAME: SuperUser IRIS_MASTER_PASSWORD: SYS IRIS_MASTER_NAMESPACE: APPINT IRIS_USERNAME: SuperUser IRIS_PASSWORD: sys WEBGW_HOST: webgateway2022 IRIS4H_HOST: irishealth ports: - "3071:1972" # 51773 is the superserver default port - "3072:52773" # 52773 is the webserver/management portal port - "3171:53773" # 53773 is the JDBC Gateway port tty: true links: - irishealth:irishealth networks: - irisenv-net iam-migrations: depends_on: - db image: intersystems/iam:2.8.1.0-3 container_name: iam-migrations hostname: iam-migrations command: kong migrations bootstrap environment: KONG_DATABASE: postgres KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam} KONG_PG_HOST: db KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam} KONG_PG_USER: ${KONG_PG_USER:-iam} KONG_CASSANDRA_CONTACT_POINTS: db ISC_IRIS_URL: 'IAM:iampassword@irishost:52773/api/iam/license' ISC_CA_CERT: ${ISC_CA_CERT} restart: on-failure links: - db:db restart: on-failure networks: - irisenv-net iam: depends_on: - irishost - db image: intersystems/iam:2.8.1.0-3 container_name: iam hostname: iam environment: KONG_ADMIN_ACCESS_LOG: /dev/stdout KONG_ADMIN_ERROR_LOG: /dev/stderr KONG_ADMIN_LISTEN: '0.0.0.0:8001' KONG_ANONYMOUS_REPORTS: 'off' KONG_CASSANDRA_CONTACT_POINTS: db KONG_DATABASE: postgres KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam} KONG_PG_HOST: db KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam} KONG_PG_USER: ${KONG_PG_USER:-iam} KONG_PROXY_ACCESS_LOG: /dev/stdout KONG_PROXY_ERROR_LOG: /dev/stderr KONG_PORTAL: on KONG_VITALS: on KONG_PORTAL_GUI_PROTOCOL: http KONG_PORTAL_GUI_HOST: 'localhost:8003' KONG_ADMIN_GUI_URL: 'http://localhost:8002' ISC_IRIS_URL: 'IAM:iampassword@irishost:52773/api/iam/license' ISC_CA_CERT: ${ISC_CA_CERT} irishost: '172.26.0.2' ports: - target: 8000 published: 8000 protocol: tcp - target: 8001 published: 8001 protocol: tcp - target: 8002 published: 8002 protocol: tcp - target: 8003 published: 8003 protocol: tcp - target: 8004 published: 8004 protocol: tcp - target: 8443 published: 8443 protocol: tcp - target: 8444 published: 8444 protocol: tcp - target: 8445 published: 8445 protocol: tcp restart: on-failure networks: - irisenv-net links: - db:db db: image: postgres:9.6 container_name: db hostname: db environment: POSTGRES_DB: ${KONG_PG_DATABASE:-iam} POSTGRES_PASSWORD: ${KONG_PG_PASSWORD:-iam} POSTGRES_USER: ${KONG_PG_USER:-iam} volumes: - 'pgdata:/var/lib/postgresql/data' healthcheck: test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-iam}"] interval: 30s timeout: 30s retries: 3 restart: on-failure networks: - irisenv-net depends_on: - irishost stdin_open: true volumes: pgdata: external: true networks: irisenv-net: external: true Y el "irisdpfile": FROM intersystems/iris:2022.1.0.209.0 LABEL maintainer="Ariel Arias <ariel.arias@intersystems.com>" USER root RUN apt-get -y update # Install some aditional software may be needed later RUN apt-get install -y vim nano net-tools unzip wget sudo iputils-ping links RUN echo "FROM IRISDPFILE" USER irisowner COPY ./Licencias/iris4h2023.key /usr/irissys/mgr/iris.key COPY ./enableirisuser.script /tmp/enableirisuser.script RUN iris start IRIS \ && iris session IRIS < /tmp/enableirisuser.script \ && iris stop IRIS quietly USER irisowner # add default health check HEALTHCHECK --interval=1m --timeout=10s --start-period=1m --retries=3 \ CMD /irisHealth.sh || exit 1 USER irisowner EXPOSE 1972 EXPOSE 52773 EXPOSE 53773
Artículo
Nancy Martínez · 25 sep, 2020

Opciones de descarga de archivos por FTP (todos los archivos, número de archivos): copiar archivo o mover archivo

Método: para descargar el archivo FTP desde Caché de InterSystems: Si tienes cualquier consulta, deja un mensaje por favor: ClassMethod FTPDownload(myFTP = "", myUserName = "", myPassword = "", sFileLocation = "", dLocation = "", noOfdownloadFile = 1, sourceFileDel = 0){ /*--------------------------------------------------------------------------------------------------------------------------- descargar el archivo según los requirimientos: FTP Método: Resuable creado por: Sanjib Raj Pandey el 30/03/2018 downLoadFile = Número de archivos o todos los archivos ...... que quieras descargar; EL VALOR PREDETERMINADO ES 1 = indica un valor, por ej. 1,3,7,100 archivos = escribe "*" para descargar todos los archivos. SourceFileDel = Si quieres eliminar los arhivos del directorio de origen después de la descarga..... entonces configura el valor 1 -- ; el valor predeterminado es: 0 1= True (elimina el archivo de la carpeta de origen después de la descarga), 0 = False (solo copiar) sFileLocation = Ubicación de origen del archivo (carpeta) dLocation = Carpeta de destinoEjemplo: La siguiente línea ..... mueve todos los archivos desde el origen a la ubicación de destino w ##class(CW.COMMON).FTPDownload("Dirección IP","Usuario","Password","Ruta origen","Ruta destino,"*",1) La siguiente línea...... copia 200 archivos desde la carpeta de origen a la de destinow ##class(CW.COMMON).FTPDownload("Dirección IP ","Usuario","Password","Ruta origen","Ruta destino",200,0) ------------------------------------------------------------------------------------------------------------------------- */ // puedes configurar el control de errores a, por ejemplo, Try and Catch Set (count,fileNo,key,messge,fileStream,myFileName,myFile,fSave,eMessage,eSubject)="" Set fIp= myFTP Set fUserName= myUserName set fPassword=myPassword set sFileLocaion=sFileLocation set dLocation=dLocation Set downloadFile=noOfdownloadFile Set sourceFileDel=sourceFileDel If $Length(fIp)=0||($L(fUserName)=0)||($L(fPassword)=0) || ($L(downloadFile)=0) Q "Credenciales inválidas o el archivo de descarga es 0.!, verifica la IP, Usuario, password o Ubicación o destino del FTP!" Set myFtp=##class(%Net.FtpSession).%New() Set eMessage="La conexión FTP falló, por favor comprueba "_fIp_" o el usuario, password.!" Set eSubject ="Mensaje de advertencia de FTP." Set myFtp.Timeout = 60 If 'myFtp.Connect(fIp,fUserName,fPassword) Quit w $$EVEMAIL^CW.COMMON(eSubject,eMessage) Do myFtp.SetDirectory(sFileLocaion) If 'myFtp.NameList(" ",.x) Quit "Fichero(s) no encontrados " Set fileStream = ##class(%Stream.FileBinary).%New() Set message ="copiado" Set myFileName="" Set fileNo=0 Set Key="" If (downloadFile = "*") { While (x.GetNext(.Key))'="" { Do StartCopy }Do myFtp.Logout()Quit fileNo_" Fichero(S) se han "_message_"con éxito !" } If (downloadFile >0) { Set count=1 While ((count <= downloadFile) && (count<=x.Count())) { do StartCopy Set count=count +1 } Do myFtp.Logout() Quit fileNo_" Fichero(S) se han "_message_"con éxito !" } StartCopy Set myFileName= x.GetNext(.fileNo) Do myFtp.Binary() Do myFtp.Retrieve(myFileName,.fileStream) Set myFile= ##class(%Library.FileBinaryStream).%New() Set myFile.Filename=dLocation_myFileName Do myFile.CopyFrom(fileStream) Set fSave=myFile.%Save() IF ((sourceFileDel=1) && (fSave = 1)) { Do myFtp.Delete(myFileName) Set message="Movidos"}
Artículo
Ricardo Paiva · 28 oct, 2021

Generadores de documentación estática

¡Hola comunidad! En el pasado, la documentación técnica del código fuente y de los productos de software se generaba en archivos chm, pdf y generadores de documentación de los propios lenguajes de programación. Este enfoque antiguo tenía las siguientes limitaciones: Documentación obsoleta, Documentación no interactiva y difícil de consultar, Diseño poco amigable y que no se adhiere a HTML, Imposibilidad de personalizar el diseño de los documentos, Imposibilidad de tener documentación en HTML 5 online y offline. Falta de soporte a Markdown. Hoy en día, existen varias soluciones de generación de documentación que producen Portales de Documentación Web muy atractivos, interactivos y con opciones estáticas y dinámicas, con soporte total para HTML 5 y más recientemente Markdown. Consulta la tabla con las opciones de código abierto más populares: Documentation Product Stars MkDocsGithub Repo: https://github.com/mkdocs/mkdocs Static and dynamic documentation generation Simple and lightweight and built in Python Smart full-text search box Multiple themes and plug-ins Support to Markdown and HTML Integration with Git pages Extensible using Python SPA architecture 11.4k DocsifyGithub Repo: https://github.com/docsifyjs/docsify No statically built html files Simple and lightweight (~21kB gzipped) Smart full-text search plugin Multiple themes Useful plugin API Compatible with IE11 Support SSR Support embedded files 16.5k DocusaurusGithub: https://github.com/facebook/docusaurus/ Powered by Markdown Built Using React Ready for Translations Document Versioning Document Search Quick Setup 21.4k SlateGithub: https://github.com/slatedocs/slate Clean, intuitive design Single page documentation Markdown support Out-of-the-box syntax highlighting Write code samples in multiple languages Automatic, smoothly scrolling table of contents Documentation is editable by users via Github RTL Support 31.9k GitBookhttps://www.gitbook.com/ Clean, intuitive design Collaborative work/text edition Support to drafts and versioning Single page documentation Markdown support Out-of-the-box syntax highlighting Write code samples in multiple languages Automatic, smoothly scrolling table of contents The better integration with Github Multiple output formats (PDF, HTML5, epub,etc.) Cloud hosting, with free plans to personal projects and paid plans to business use cases 500,000 users La aplicación IRIS Publisher, en Open Exchange, permite extraer bloques de documentación XData en HTML o Markdown y generar un sitio web con la documentación de tu app, utilizando MkDocs. Consulta las instrucciones en el siguiente artículo de esta serie: Cómo crear el Portal de Documentación para InterSystems IRIS Referencia: 5 free static documentation generators you must check out
Artículo
Ricardo Paiva · 16 sep, 2021

Base de datos documental (DocDB) - Ejemplos de llamadas API REST - Colección Postman

Como ayuda para aquellos que quieren utilizar las funciones de la [Base de datos documental](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB_intro) (DocDB) dentro de InterSystems IRIS, y específicamente la [API REST](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GDOCDB_rest) que proporciona, reuní una [Colección](https://www.postman.com/product/api-client/) [Postman](https://www.postman.com/collection/) que ofrece muestras para varias llamadas básicas. Por ejemplo: ![](/sites/default/files/inline/images/images/image(1316).png) En el ejemplo se utilizan documentos de "Color", por ejemplo, Rojo, Azul, etc., utilizando una estructura JSON de muestra desde [aquí](https://www.sitepoint.com/colors-json-example/). La Colección incluye llamadas de diferentes "categorías": * Crear metadatos: crear la base de datos y las propiedades relacionadas * Obtener metadatos: entender qué bases de datos y propiedades están definidas * CUD: crear/actualizar/eliminar documentos * Buscar y obtener documentos: recuperar documentos según el ID o ciertos valores o criterios * Eliminar metadatos: eliminar propiedades o bases de datos El orden de las solicitudes en la Colección tiene cierta lógica interna (por ejemplo, primero crear la base de datos y las propiedades, luego insertar algunos datos y después recuperarlos), pero por supuesto puedes utilizarlos en el orden o los cambios que desees. El orden también funciona bien si se ejecuta [Collection Runner](https://learning.postman.com/docs/running-collections/intro-to-collection-runs/) de Postman. Añadí algunos [scripts de prueba](https://learning.postman.com/docs/writing-scripts/test-scripts/) básicos, que permiten que Postman muestre el estado Aprobado o Fallido para cada llamada. Por ejemplo: ![](/sites/default/files/inline/images/images/image(1317).png) Ten en cuenta que la última llamada **elimina todas las bases de datos de documentos dentro de un Namespace**, así que no ejecutes esto a menos que realmente quieras hacerlo... no lo hagas manualmente y tampoco como parte de la ejecución de toda la Colección. Para conseguir que las llamadas funcionen en varios entornos, utilicé la función [variables](https://learning.postman.com/docs/sending-requests/variables/) de Postman. Esto permite cambiar el nombre/la IP del servidor, el puerto y el namespace - ![](/sites/default/files/inline/images/images/image(1320).png) Así que cada llamada se parece a esto: ![](/sites/default/files/inline/images/images/image(1321).png) Seguramente también necesitarás adaptar la parte de autenticación. Actualmente tengo "Basic Authentication" simplemente con "SuperUser" y "sys": ![](/sites/default/files/inline/images/images/image(1327).png)   Solo para añadir un _**cambio "multimodelo"**_ a esto, aquí también hay un ejemplo de acceso a estos datos a través de SQL: Esta es la estructura de la tabla (como se ve en la extensión SQL Tools en VSCode): ![](/sites/default/files/inline/images/images/image(1322).png) Este es un resultado SELECT sencillo: ![](/sites/default/files/inline/images/images/image(1323).png) Y aquí hay un SELECT con una cláusula WHERE sobre una de las propiedades que definimos: ![](/sites/default/files/inline/images/images/image(1324).png)
Pregunta
Yone Moreno · 28 mar, 2022

TCP y DICOM: Investigar opciones de invocación del servicio

Buenos días, Agradeceríamos el apoyo de ustedes: Desarrollando una integración para realizar un circuito "Query / Retrieve" con estudios de imágenes médicas DICOM, necesitaríamos lo siguiente: Opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración, alternativas a la opción por linea de comando En concreto hemos leído: Recibir documento DICOM con un PDF embebido y metadatos Adaptando el ejemplo, empleamos la línea: ./storescu -b VNAPRE -c ESBPRE@10.136.4.XYZ:19ABC ./embeddedpdf.dcm Mediante la cual simulamos el envío de un documento DICOM con un PDF Sin embargo, esto no nos es fructífero, provechoso o de solución, ya que lo que se necesita actualmente, es simular consultas del tipo "FIND". En concreto necesitaríamos consultas del tipo "Obtener Resultados a nivel de Estudios" StudyRootQuery - FIND u "Obtener Estudios a nivel de Pacientes" PatientRootQuery - FIND // StudyRootQuery - FIND set tAffectedSOPClassUID="1.2.840.10008.5.1.4.1.2.2.1" // PatientRootQuery - FIND ;set tAffectedSOPClassUID="1.2.840.10008.5.1.4.1.2.1.1" Hemos indagado cómo simular las llamadas FIND: Query / Retrieve scenario En particular probamos desde la "Salida" del Studio enviando el expediente del paciente en el campo "PatientID" del "DataSet" del documento DICOM: do ##class(DICOM.BS.QueryService).TestFind("13168299") Y de esta forma simularíamos una llamada al Servicio "dummy" cuya clase es: DICOM.BS.QueryService Sin embargo, ¿ qué opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración existen ? ¿ Existe un SoapUI / POSTMAN / herramienta línea comando y/o visual, que nos permita simular comandos FIND de DICOM por TCP ? Gracias por leernos y por sus respuestas Además hemos leído: https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_intro#EDICOM_intro_samples https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_storage_production https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_associations https://es.community.intersystems.com/post/dicom-no-hay-asociaci%C3%B3n-activa-para-calling-aet-yyy-y-called-aet-aaa-%E2%B8%98-%E2%80%BD https://community.intersystems.com/post/dicom-tcp-services-and-dicom-implementation-details-ensemble A nivel visual, ahora estamos probando el circuito mediante un Servicio "dummy", cuya clase es: DICOM.BS.QueryService Sin embargo, necesitamos encontrar la vía de simular ser el sistema origen, es decir, probar el servicio TCP, siendo de la clase: EnsLib.DICOM.Service.TCP ¿ Qué opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración, alternativas a la opción por linea de comando, existirían ? ¿ De qué forma lo harían ustedes ? ¿Disponen de ejemplos, documentación, código, referencias o indicaciones que pudieran servir de apoyo? Muchas gracias de antemano Un saludo Hola Yone, Imagino que te refieres al ejemplo https://github.com/intersystems-ib/iris-dicom-sample Los comandos C-FIND son mensajes DICOM que deben tener el formato correcto y transmitirse usando el protocolo DICOM. Por eso, o usas un simulador, o generas ese mensaje desde Ensemble / Health Connect. En el ejemplo, el comando do ##class(DICOM.BS.QueryService).TestFind() provoca la generación de un mensaje C-FIND dentro de la producción para un paciente concreto. El simulador dcm4che tiene la utilidad findscu que permite simular la generación de mensajes C-FIND.
Artículo
Muhammad Waseem · 8 ago, 2022

Cómo medir las emisiones de gases de efecto invernadero (GHG) con la aplicación Carbon Footprint Counter

La aplicación Carbon Footprint Counter utiliza el GHG Protocol para medir las emisiones de carbono en las empresas. El Protocolo de Gases de Efecto Invernadero (GHG Protocol) establece marcos estandarizados globales integrales para medir y gestionar las emisiones de gases de efecto invernadero (GHG) de las operaciones del sector público y privado, las cadenas de valor y las acciones de mitigación. Sobre la base de una asociación de 20 años entre el Instituto de Recursos Mundiales (WRI) y el Consejo Empresarial Mundial para el Desarrollo Sostenible (WBCSD), el GHG Protocol trabaja con gobiernos, asociaciones industriales, ONGs, empresas y otras organizaciones. (fuente: https://ghgprotocol.org/about-us). La aplicación Carbon Footprint Counter utiliza InterSystems IRIS para implementar APIs REST y la base de datos SQL para administrar el inventario de emisiones de carbono en las empresas. La interfaz es Angular 12 con el framework PrimeNG (líder de código abierto para Angular). Factores de emisión Para medir las emisiones de carbono de la empresa, la aplicación almacena 300 factores de emisión distribuidos en 4 segmentos (inmóvil, móvil, transporte y electricidad comprada). Cada factor, como el gas natural, la gasolina, el transporte en autobús, el transporte aéreo, los viajes en automóvil, etc., tiene valores de referencia para calcular las emisiones de co2, ch4 y n2o. Así: Emisiones inmóviles (stationary) El GHG Protocol define inmóvil como el consumo de combustible en una instalación para producir electricidad, vapor, calor o energía. La combustión de combustibles fósiles por parte de calderas de gas natural, generadores diésel y otros equipos emite dióxido de carbono, metano y óxido nitroso a la atmósfera. Puedes registrar tus emisiones inmóviles en el menú y la ventana de Combustión inmóvil (Stationary Combustion): Emisiones de combustión móvil El GHG Protocol define la combustión móvil como el consumo de combustible de los vehículos que son propiedad de la empresa o alquilados. La combustión de combustibles fósiles en vehículos (incluyendo automóviles, camiones, aviones y barcos) emite dióxido de carbono, metano y óxido nitroso a la atmósfera. Puedes registrar tus emisiones móviles en el menú y la ventana de Combustión móvil: Emisiones del transporte El GHG Protocol define el transporte como el consumo de combustible de los vehículos utilizados para realizar viajes de empresa. Los ejemplos incluyen viajes aéreos comerciales y el uso de vehículos alquilados durante viajes de negocios. Puedes registrar tus emisiones de transporte en el menú y la ventana de Transporte: Emisiones de electricidad El GHG Protoco define las emisiones de electricidad como energía comprada a las empresas de servicios locales (no se quema en el sitio). Los ejemplos incluyen electricidad, vapor y agua fría o caliente. Para generar esta energía, las empresas de servicios queman carbón, gas natural y otros combustibles fósiles, emitiendo dióxido de carbono, metano y óxido nitroso en el proceso. Puedea registrar tus emisiones de electricidad en el menú y la ventana de Emisiones de electricidad: Cálculo de las emisiones totales de carbono La aplicación computa todas las emisiones registradas: Pasar a la acción Ahora, tu empresa puede saber sus emisiones de carbono anuales y tomar medidas para compensar las emisiones. Se pueden comprar créditos de carbono, hacer donaciones a WWF, Greenpeace u otras instituciones... Calcúlalo ahora usando https://openexchange.intersystems.com/package/Carbon-Footprint-Counter.