Python
El lado Python de AnP no sigue los modelos estándares de Python a la hora de modular un proyecto,
modulándolo a partir de ficheros que luego serán cargados, precompilados y ejecutados a modo de
importación o inclusión dentro del proyecto haciendo que el lado Python pase de ser un entorno
compilable a ser únicamente un entorno precompilable. Dicha filosofía de trabajo se basa en el alto
rendimiento de ejecución de Python con respecto a las necesidades que existen para el uso y
ejecución del AnP, eliminando un proceso que daría mucha rigidez al código así como el sistema de
ficheros __init__.py para modular los directorios, permitiendo también la
inclusión o importación de elementos y librerías externos al directorio del proyecto AnP. El
problema de los ejecutables se arregla rápidamente con un Script Bash SH en los casos Unix (Linux,
MacOS Android, etc.); o un fichero Batch para los casos DOS (Windows).
Continuando con la filosofía de trabajo de este proyecto, el GUI se basa en un entorno Web en un
navegador cualquiera que posea el OS, aunque también se puede hacer uso de un entorno Core
únicamente para Terminal y COMANDOS y consigo, extender a una ventana, pero está más orientado a una
gestión GUI sobre un navegador Web para gestión de aplicaciones Web.
La filosofía de trabajo de AnP establece que es una clase la cual debe de ser extendida dentro de la
clase del proyecto donde se quiera aplicar, a no ser que éste lo use de librería externa para
compartir entre proyectos u otros detalles pues por cada proyecto donde se extienda se creará un
nuevo AnP.
Finalmente decir que AnP separa los elementos comunes de sus librerías en una librería llamada
AnP.Common, la cual se integra dentro de un nivel de una clase AnP que dejará de existir cuando se
cree la librería principal Anp, pues ésta extiende de sus propios elementos comunes, no siendo los
elementos comunes la librería principal, quedando AnP simplemente para gestionar las librerías y el
arranque del proyecto.
Para conseguir la filosofía de separar los elementos comunes de la gestión global del proyecto AnP
se usa un fichero llamado "include.py" que es el encargado de incluir todas las librerías que se
deseen del propio proyecto. Para poder llevar a cabo dicha tarea a partir de la preconmpilación
podemos trabajar con la creación de dos variables las cuales son:
- root (required): Indica el directorio Python del proyecto AnP. Esta variable es obligatoria pues donde se precompile dicho proyecto será el directorio que se tome como directorio raiz si no se le especifica. Una opción a tener en cuenta para su tratamiento es que a la par que se conoce el Path fichero "include.py" del proyecto AnP, se entiende que también se conoce el Path de dicho directorio, y por lo tanto ha de ser adjunto mediante la creación de dicha variable. Si dicha variable no se especifica, include.py cogerá como directorio Python el que obtenga a partir del os.path.dirname de Python.
- libraries (optional): Es un vector, da igual que lista o tupla, donde se le especifican las librerías a adjuntar. Si no se le especifica dicho vector, include.py cargará todas las librerías Python del proyecto AnP, sean usadas o no, con su correspondiente aumento de peso tanto en memoria como en proceso.
Para llevar a cabo dichas tareas se puede seguir el siguiente ejemplo genérico:
-
Language
py
-
Lines
20
-
Characters
513
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os.path import dirname as directory_name
from os.path import abspath as path_absolute
from os.path import exists as path_exists
root = directory_name(path_absolute(__file__)) + "/../../../AnP/Python/"
path = root + "include.py"
if path_exists(path):
with open(path) as data:
exec(compile(data.read(), "include", "exec"), globals())
class Proyecto(AnP):
def __init__(self):
super().__init__()
proyecto = Proyecto()
IMPORTANTE: El proyecto AnP está diseñado para que se puedan usar caracteres, no
solo UTF-7, sino más globalizado, por lo que se aconseja utilizar las cabeceras de Python para UTF-8
como se muestra en el ejemplo.
IMPORTANTE: Para poder enviar las variables globales contra la precompilación y
ejecución es muy importante establecer las variables globales en la ejecución, como sale en el
ejemplo con el "globals()".
IMPORTANTE: En el ejemplo se ve como la clase Proyecto extiende de AnP, y en su
constructor hace llamada al constructor de AnP pues si no se construye AnP, muchos elementos de la
carga de AnP estarán incompletos.
Es importante antes de empezar decir que la librería AnP se basa en la distinción de Python 2 y
Python 3 pese a las diferencias que pueda haber entre subversiones, y siempre existirá dicha
distinción si la sintaxis no cambia para versiones futuras, y de ahí que esta librería no sea
compatible con Python 1 por el cambio de sintaxis en métodos globales como "print" y otros.
Y para finalizar la presentación de Python, es importante tener encuenta el diagrama de flujo
interno a la hora de cargar las librerías, el cual es el siguiente:
-
Language
mermaid
-
Lines
3
-
Characters
80
graph TD
anp[AnP] -->|extends| common[AnP.Common]
anp -->|remove| common
NOTA: AnP usa la referencia en memoria que posee tras haber extendido AnP.Common, de
esta forma se puede eliminar dicha variable o entorno. La eliminación se lleva a cabo puesto que
AnP.Common se crea antes que AnP, creando una clase AnP no funcional; tras ello AnP se carga
copiando la referencia en una variable temporal que usará para extender, luego eliminará la clase
AnP del AnP.Common y se proclama como la clase AnP principal extendiendo AnP.Common a partir de la
variable temporal que se creó.
Crear proyecto
PAra crear un proyecto basado en AnP sobre Python primero hemos de crear el directorio del proyecto,
ya sea partiendo de un proyecto Git o un proyecto local. Siguiendo el estándar de AnP, lo siguiente
es crear la siguiente estructura de directorios sobre el raíz del directorio del proyecto:
- JSON: Este directorio contendrá todos los ficheros del lado servidor del proyecto.
- Public: Este directorio contendrá toda la parte pública cliente del programa.
- Python: Este directorio contendrá todo lo relacionado con Python.
Para continuar, hemos de crear dos ficheros básicos dentro del directorio "Python" los cuales serían
uno para el propio programa que queremos crear, el cual extienda del AnP o derivado del AnP; y otro
que sea el fichero de inclusiones, ya sea por parte del propio AnP, como de posibles programas de
extensión, así como los propios del proyecto. Para dicha tarea tendríamos el siguiente fichero
"include.py", que será el que arranca el programa tal que así:
-
Language
py
-
Lines
53
-
Characters
1559
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os.path import dirname as directory_name
from os.path import abspath as path_absolute
from os.path import exists as path_exists
example_root = directory_name(path_absolute(__file__)) + "/.."
anp_root = example_root + "/../AnP"
root = anp_root + "/Python/"
anp_include = root + "include.py"
if path_exists(anp_include):
with open(anp_include, "rb") as data:
exec(compile(data.read(), "AnP.include", "exec"), globals())
root = example_root + "/Python/"
for file in [
"Example",
# Other custom project files...
# Procedures
"Procedures/Example.Procedures.Proc0",
"Procedures/Example.Procedures.Proc1",
"Procedures/Example.Procedures.Proc2",
"Procedures/Example.Procedures.Proc3",
# ...
"Procedures/Example.Procedures.ProcN",
# Controllers
"Controllers/Example.Controllers.Ctrl0",
"Controllers/Example.Controllers.Ctrl1",
"Controllers/Example.Controllers.Ctrl2",
"Controllers/Example.Controllers.Ctrl3",
# ...
"Controllers/Example.Controllers.CtrlN"
]:
path = root + file + ".py"
if path_exists(path):
print(["ok", path])
with open(path, "rb") as data:
exec(compile(data.read(), file, "exec"), globals())
else:
print(["no", path])
example = Example({
"roots" : [example_root, anp_root],
"settings_files" : example_root + "/JSON/Example.py.settings.json",
"secrets_files" : example_root + "/Example.secrets.json"
})
Dentro del directorio de "Python" crearemos otros dos directorios: uno para los pseudo
procedimientos almacenados en caso de hacer uso de bases de datos o datos que no tienen un motor de
interpretación completo; y otro para los controladores.
NOTA: De manera estándar, el directorio de los procedimientos almacenados, para
entornos de datos planos, de marcas o SQLite, entre otros, se llamaría "Procedures"; y el de los
controladores sería "Controllers". No pilla automáticamente los contenidos de los directorios el
propio AnP para hacer ahorro de recursos de lecturas contra el disco y agilizar la aplicación en la
medida de lo posible, por lo que requiere de ser mapeados directamente sobre el "include.py".
Dentor del "include.py" se requiere de especificar el directorio raíz en un Path absoluto del AnP,
cualquier programa extendido con el AnP y el propio directorio principal del proyecto que queremos
llevar a cabo, en el orden inverso al dicho puesto que determinará la prioridad de llamamiento.
Por otro lado, tenemos el o los archivos de configuración que queramos agregarle. Es importante
destacar que las propiedades son sobreescribibles por lo que si algún programa extendido tiene
configuración customizada, se aconseja que éste lo implemente dentro de los ficheros de
configuración por defecto "defaultsettingsfiles" incluyendo el AnP y sus extensiones en el orden
dicho para su prioridad dentro de la implementación de la configuración, dejando para dicho proyecto
el parámetro de configuración "settings_files" los Path de los ficheros de configuración del
proyecto que queremos llevar a cabo.
Finalmente, es importante implementar el archivo Secrets, archivo que nos servirá para
independizarlo del proyecto general, ya sea externalizándolo del proyecto en cuestión o ignorándolo
con el ".gitignore", donde pondremos parámetros de configuración locales y datos sensibles del
proyecto en nuestro entorno local.
Continuando con la forma base de nuestro nuevo programa basado en AnP, el fichero principal que
extiende de AnP ha de construir también a su padre, ya sea el AnP o extensión del mismo, tal como se
ve a continuación:
-
Language
py
-
Lines
8
-
Characters
145
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Example(AnP):
def __init__(self, input = None):
super().__init__(input)
El fichero del ".gitignore" tendría que ser tal que así:
-
Language
.gitignore
-
Lines
1
-
Characters
20
Example.Secrets.json
NOTA: LA línea del Secrets en el ".gitignore" puede ser comentada mientras se trabaja
para tenerla visible en IDEs tales como Atom entre otros que puedan ocultarlo por disposición del
mismo fichero. Para comentar la línea usar el caracter "#" como encabezado de la misma.
Ahora vamos al directorio de JSON e implementamos el fichero de configuración de nuestro programa
con la configuración del modo de trabajo de los datos (Por defecto es SQLite, ver información en el
proyecto AnP); nombre de la variable de datos entre el cliente y el servidor (Por defecto es anp); y
la gestión manual de los controladores.
-
Language
json
-
Lines
11
-
Characters
344
{
"base_mode" : "sqlite",
"web_server_variables_name" : "tests",
"controllers" : {
"controller_1" : "Tests.Controllers.Controller1",
"controller_2" : "Tests.Controllers.Controller2",
"controller_3" : "Tests.Controllers.Controller3",
"controller_n" : "Tests.Controllers.ControllerN"
}
}
Luego hemos de poner el fichero de rutas, donde pondremos las rutas que requiramos para el
funcionamiento de nuestro proyecto, como ejemplo de rutas públicas y un controlador de pruebas puede
ser el siguiente:
-
Language
json
-
Lines
8
-
Characters
92
[
"get:/test test@tests",
"get:/anp /../AnP/Public",
"get:/ /Public"
]
NOTA: Es importante destacar que las rutas públicas del AnP y de sus posibles
extensiones, haya que agregarlas manualmente con una extensión para evitar solapamiento de
peticiones entre proyectos. En el ejemplo tenemos al AnP con un encabezado "/anp", mientras que el
proyecto de pruebas va sobre el raíz. Es importante el orden puesto que el raíz solaparía a todas
las demás rutas.
Para terminar con todo, simplemente nos hace falta el fichero Secrets, el cual nos permite gestionar
configuraciones con datos de alta sensibilidad entre otras cosas. Un ejemplo de ello puede ser el
siguiente:
-
Language
json
-
Lines
21
-
Characters
472
{
"print_types" : true,
"connections" : [{
"name" : "AnPSQLite",
"type" : "SQLite",
"file" : "C:\\Data\\AnP.sqlite.db"
}],
"web_servers" : [{
"name" : "AnPRM_WS",
"port" : 8087,
"hosts" : "localhost",
"simultaneous_connections" : 100,
"routes" : {
"routes" : [
"/../AnP/JSON/AnP.py.routes.json",
"/JSON/Tests.py.routes.json"
],
"root" : "C:\\Tests"
}
}]
}
En este fichero se pueden poner accesos a las bases de datos, configuraciones custom, accesos a los
servidores, etc.
Finalmente, es importante tener los ficheros de arranque de la aplicación, los cuales varían según
el entorno, existiendo dos: el Batch (Para entornos DOS y Windows) y el Bash (Para entornos UNIX),
los cuales se colocarían en el raíz del proyecto con el nombre de la aplicación para identificar al
fichero de ejecución del programa.
Batch |
Bash |
-
Language
bat
-
Lines
29
-
Characters
746
@echo off
set executed=false
for /d %%D in (c:\*) do (
if exist %%~fD\python.exe (
%%~fD\python.exe %cd%\Python\include.py
set executed=true
cmd /c
)
)
if %executed% equ false if exist %UserProfile%\AppData\Local\Programs\Python\ (
for /d %%D in (%UserProfile%\AppData\Local\Programs\Python\*) do (
if exist %%~fD\python.exe (
%%~fD\python.exe %cd%\Python\include.py
set executed=true
cmd /c
)
)
)
if %executed% equ false (
echo ERROR. It required install Python.
echo Please, go to https://www.python.org/downloads/ and install Python.
echo If you don't know to do it or you don't feel secure, please, contact with any tecnician.
echo Please, press any key to continue.
set /p input=
)
|
-
Language
sh
-
Lines
9
-
Characters
259
#!/bin/bash
if [[ "$(python3 -V)" =~ "Python 3" ]]; then
python3 Python/include.py
elif [[ "$(python -V)" =~ "Python" ]]; then
python Python/include.py
else
echo "You need to install Python. You can use the default repositories of your system."
fi
|
AnP.Common.py
Esta librería es la librería donde se encuentran todos los elementos comunes del lado Python de AnP.
Aunque sea la primera librería para la importación, esto no indica que sea la librería principal,
quedando como la principal AnP.py, esta librería simplemente contendrá metodos y variables comunes
para la librería principal, así como estructuras comunes cortas como la creación y gestión de Hashes
entre otras opciones.
Para documentar esta librería nos centraremos en las diferentes funciones o variables de las que se
compone para uso global.
AnP.is_dos
AnP.is_unix
AnP.python2
Método estático que retorna un valor Booleano que verifica si se está ejecutando en Python 2 o no.
AnP.python3
Método estático que retorna un valor Booleano que verifica si se está ejecutando en Python 3 o no.
AnP.is_bool
Método estático que retorna un valor Booleano que verifica si la variable enviada es de tipo
Booleana o no.
-
Language
py
-
Lines
6
-
Characters
204
print("YES" if AnP.is_bool(0) else "NO") # NO
print("YES" if AnP.is_bool(True) else "NO") # YES
print("YES" if AnP.is_bool(False) else "NO") # YES
print("YES" if AnP.is_bool("True") else "NO") # NO
AnP.is_array
Método estático que retorna un valor Booleano que verifica si la variable enviada es un Array o no.
Para validar si es un Array o no en Python, puesto que este lenguaje no posee como tal un tipado
concreto para éste, se verifica si es de tipo lista (list) o tupla (tuple), siendo la diferencia
entre ambas que la tupla es un vector rígido y la lista un vector dinámico.
-
Language
py
-
Lines
6
-
Characters
207
print("YES" if AnP.is_array(0) else "NO") # NO
print("YES" if AnP.is_array([]) else "NO") # YES
print("YES" if AnP.is_array((0,)) else "NO") # YES
print("YES" if AnP.is_array(("jojo")) else "NO") # NO
AnP.is_list
Método estático que retorna un valor Booleano que verifica si la variable enviada es una lista o no.
-
Language
py
-
Lines
6
-
Characters
206
print("YES" if AnP.is_array(0) else "NO") # NO
print("YES" if AnP.is_array([]) else "NO") # YES
print("YES" if AnP.is_array((0,)) else "NO") # NO
print("YES" if AnP.is_array(("jojo")) else "NO") # NO
AnP.is_tuple
Método estático que retorna un valor Booleano que verifica si la variable enviada es una tupla o no.
-
Language
py
-
Lines
6
-
Characters
206
print("YES" if AnP.is_array(0) else "NO") # NO
print("YES" if AnP.is_array([]) else "NO") # NO
print("YES" if AnP.is_array((0,)) else "NO") # YES
print("YES" if AnP.is_array(("jojo")) else "NO") # NO
AnP.is_dictionary
Método estático que retorna un valor Booleano que verifica si la variable enviada es un diccionario
o no.
-
Language
py
-
Lines
6
-
Characters
200
print("YES" if AnP.is_array(0) else "NO") # NO
print("YES" if AnP.is_array([]) else "NO") # NO
print("YES" if AnP.is_array((0,)) else "NO") # NO
print("YES" if AnP.is_array({}) else "NO") # YES
AnP.is_string
Método estático que retorna un valor Booleano que verifica si la variable enviada es un string o no.
-
Language
py
-
Lines
6
-
Characters
198
print("YES" if AnP.is_array(0) else "NO") # NO
print("YES" if AnP.is_array([]) else "NO") # NO
print("YES" if AnP.is_array("") else "NO") # YES
print("YES" if AnP.is_array({}) else "NO") # NO
AnP.is_function
Método estático que retorna un valor Booleano que verifica si la variable enviada es una función o
no.
-
Language
py
-
Lines
9
-
Characters
232
def test():
pass
print("YES" if AnP.is_array(0) else "NO") # NO
print("YES" if AnP.is_array(lambda:0) else "NO") # YES
print("YES" if AnP.is_array(test) else "NO") # YES
print("YES" if AnP.is_array({}) else "NO") # NO
AnP.is_number
Método estático que retorna un valor Booleano que verifica si la variable enviada es un número o no.
-
Language
py
-
Lines
7
-
Characters
253
print("YES" if AnP.is_array(0) else "NO") # YES
print("YES" if AnP.is_array("1") else "NO") # NO
print("YES" if AnP.is_array(.8) else "NO") # YES
print("YES" if AnP.is_array(-6.23) else "NO") # YES
print("YES" if AnP.is_array({}) else "NO") # NO
AnP.is_integer
Método estático que retorna un valor Booleano que verifica si la variable enviada es un número
entero o no.
-
Language
py
-
Lines
7
-
Characters
251
print("YES" if AnP.is_array(0) else "NO") # YES
print("YES" if AnP.is_array("1") else "NO") # NO
print("YES" if AnP.is_array(.8) else "NO") # NO
print("YES" if AnP.is_array(-6.23) else "NO") # NO
print("YES" if AnP.is_array({}) else "NO") # NO
AnP.is_datetime
Método estático que retorna un valor Booleano que verifica si la variable enviada es un objeto de
tipo fecha y/o hora o no.
AnP.if_none
Método estático al cual se le mandan dos valores donde si el primero es nulo (None) éste retornará
el segundo, haciendo referencia al isnull de SQL Server y al ifnull de MySQL. Para evitar un
preprocesamiento inútil se permite que el segundo parámetro sea una función, ya sea Lambda o una
función predefinida y el valor devuelto en caso de que el primero sea nulo, será la respuesta a la
llamada de dicha función.
AnP.string_variables
Método estático que permite procesar variables en un String dado, entiendendo que las variables
dentro del String sean nombradas estableciendo su Key entre llaves, siendo substituídos por el valor
que se le determine en las variables. En caso de no encontrarse un valor en las variables, éste
devolverá el valor por defecto, a no ser que éste sea nulo, que será cuando se devolverá de nuevo su
estado original incluyendo las llaves. La entrada de variables puede ser nula, lo cual no haría
nada; un diccionario donde vuscar el valor a la llave del String; o una lista o tupla de
diccionarios con la misma finalidad.
AnP.get_directory_path
AnP.make_directories
IMPORTANTE: Los permisos del mismo quedarán exclusivizados al usuario ejecutor del
Python, y dará una excepción si no tiene permisos o el Path del mismo está mal sintácticamente o no
pertenece a ninguna unidad.
AnP.paths_get
La lista de Paths resultante será una lista de Paths a partir de como se estructure en la
configuración a partir del siguiente orden de prioridad:
- Path dado.
- Path absoluto de la aplicación.
- Path relativo anterior al de la ejecución.
- Path relativo desde la ejecución.
- Paths roots dados.
- Paths establecidos como "root".
- Paths establecidos como "roots".
AnP.file_load
NOTA: El contenido cargado será de caracter binario en Python 3.
IMPORTANTE: El contenido será None si no se encuentra el fichero.
AnP.json_decode
IMPORTANTE: Si el formato del String no es un JSON retornará None.
AnP.json_encode
IMPORTANTE: Si el objeto dado no es serializable y codificable en JSON retornará
None.
AnP.base64_decode
IMPORTANTE: Si la codificación es errónea retornará None.
AnP.base64_encode
IMPORTANTE: Si No es un String o da problemas su codificación, éste retornará
None.
AnP.shell
IMPORTANTE: Si la ejecución da error éste retornará None.
IMPORTANTE: Solo retorna el nivel de respuesta e ignora el nivel de error e
inserción de texto.
AnP.load_url
NOTA: Para realizar un POST sin variables ha de enviarse un diccionario vacío en el
parámetro "data".
NOTA: Este método no usa ningún método interno nativo de Python como pueden ser las
librerías "urllib", "urllib2", "urllib3", "request" o "socket" puesto que Python, de forma nativa,
espera a la finalización del Timeout, relentizando las conexiones de la aplicación o incluso
arriesgando a que la respuesta venga parcial por culpa de dicho Timeout. Para realizar dicha acción
usará la Terminal o la Consola de COMANDOS, dependiendo de la plataforma en la que se encuentre, a
partir de la librería nativa de Python "subprocess", y ejecutará el programa cURL para efectuar
dicha acción. Es importante destacar que dicho programa viene nativo en Windows 10 en su Consola de
COMANDOS, pero en Linux se requiere de instalar, lo cual puede efectuarse de la siguiente manera:
-
Language
sh
-
Lines
1
-
Characters
16
apt install curl
AnP.are_string
AnP.ternary
AnP.timestamp
AnP.timestamp_milliseconds
AnP.now
AnP.datetime
AnP.exception
AVISO: Si la base de datos no está montada, ya sea que no hay configuración para la
misma o falla cualquier punto para el montaje de la base de datos SQLite, éste no hará nada más que
almacenar en memoria las excepciones mientras el programa siga activo y en cuanto detecte que existe
la base de datos, éste insertará todas las excepciones en la misma, sino, dichas excepciones se
perderán.
AVISO: Si el Path apunta a una unidad, ésta se formateará en los casos de UNIX no
sobre el directorio raíz, sino desde el directorio de montaje "/mnt" continuando con un
subdirectorio con la letra de la unidad en minúscula siguiendo la estructura de los Subsistemas
Linux.
NOTA: Si el Path ya está formateado en el sistema requerido éste no cambiará.
AnP.procedure_exists
AnP.procedure_get
NOTA: Si no existe retornará None.
AnP._print
Hablar de la configuración, formato, tipados, filtro de impresión por tipados, uso de la I18N,
variables, etc.
NOTA: Es un método oculto para diferenciarlo del "print" nativo de Python. Parece ser
que aunque esté internamente dentro de una clase, la palabra reservada "print" da errores
inesperados.
NOTA: Este método también se encarga del almacenamiento de los LOGs, entendiéndose como
los elementos de impresión aquellos elementos importantes a mostrar o monitorizar por parte del
usuario cliente.
AnP.py
Esta librería es la encargada de iniciar y gestionar todo la clase y objeto AnP, incluyendo sus
clases y objetos anidados en ella.
AnP.is_built
AnP.Settings.py
Esta librería es la encargada de gestionar las configuraciones tanto internas del AnP como de las
aplicaciones que extiendan del propio AnP.
AnP.Settings.get
AnP.Settings.add
AnP.I18N.py
Esta librería es la encargada de gestionar los idiomas dentro del AnP y las aplicaciones que se
extiendan del mismo.
AnP.I18N.default
AnP.I18N.get
AnP.I18N.add
AnP.I18N.change
AnP.Procedures
SQLite es un sistema de datos por fichero con lenguaje SQL muy simplificado, llegando a puntos de no
poderse trabajar con procedimientos almacenados entre otras cosas. Como la ideología de trabajo del
AnP es separar cada nivel por su lenguaje y motor, en teoría, cualquier trabajo que se haga a nivel
de datos ha de trabajarse directamente sobre la propia SQL, pero como dijimos antes, la ausencia de
procedimientos almacenados impide dicha tarea por lo que se creará un punto intermedio llamados
"procedures" a nivel de Python que substituirá dicho nivel de datos.
AnP.Procedures.Users.py
Esta librería se encarga de simular la parte SQL de los procedimientos almacenados contra Python.
Validaciones
Para empezar la documentación de este fichero primero se gestionará el análisis de las validaciones
para tener una lista de errores según su posición de bit dentro del entero que los gestiona.
AnP.Procedures.Users.__session_validate
- La sesión es un valor nulo.
- La sesión no es un valor numérico entero.
- La sesión no es un ID válido.
- La sesión no existe.
- La sesión ya fue finalizada.
- La sesión ha caducado.
- Hubo un error a la hora de analizar la sesión contra la DB.
AnP.Procedures.Users.__user_data_validate
NOTA: El ID del usuario solo lo retornará en caso de no haber ningún error.
- El nick del usuario es nulo.
- El nick del usuario es un valor vacío.
- La contraseña del usuario es nula.
- La contraseña del usuario es un valor vacío.
- El usuario no existe.
- La contraseña del usuario no es correcta.
AnP.Procedures.Users.__new_user_validate
- El nick del usuario es nulo.
- El nick del usuario es un valor vacío.
- La contraseña del usuario es nula.
- La contraseña del usuario es un valor vacío.
- Ya existe un usuario con ese nick.
- Hubo nu error a la hora de analizar los datos del usuario contra la DB.
AnP.Procedures.Users.__email_validate
- El E-Mail es nulo.
- El E-Mail es un valor vacío.
- El E-Mail tiene un mal formato.
AnP.Procedures.Users.__get_ip_id
- Excepción.
- La dirección IP es nulo.
- La dirección IP es un valor vacío.
- La dirección IP tiene un mal formato.
IMPORTANTE: Terminar la validación de la IP.
F.A.Q. (Preguntas Frecuentes)
Aquí se resolverán dudas que puedan ir surgiendo a lo largo del desarrollo, como filosofías de
trabajo o tratamiento; así como otras cosas que puedan ir surgiendo a partir de comentarios de la
gente que hace uso de este sistema. Dichas dudas o preguntas se irán formulando y respondiendo como
subtítulos a este apartado.
Documentación del código
El código no estará documentado, y a lo sumo puede que aparezcan ciertas anotaciones aclaratorias de
los desarrolladores dentro del mismo código. La documentación del código se integra con la
documentación del proyecto, y como podemos ver, se dividirá en dicha documentación por lenguajes. La
filosofía de ello reside en dejar el código lo más limpio y puro posible y de esta forma facilitar
la visualización del conjunto a partir de la misma documentación.