[[post_data {
    "author" : "KyMAN",
    "since" : 20210825,
    "version" : 20210825
}]]
# 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í:

```py
#!/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.

> [[! note 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 "default_settings_files" 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:

```py
#!/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í:

```.gitignore
Example.Secrets.json
```

> [[! note 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.

```json
{
    "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:

```json
[

    "get:/test test@tests",

    "get:/anp /../AnP/Public",
    "get:/ /Public"

]
```

> [[! note 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:

```json
{
    "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.

<table style="width:100%;">
    <thead>
        <tr>
            <th style="width:50%;">Batch</th>
            <th style="width:50%;">Bash</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>

```bat
@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=
)

```

            </td>
            <td>

```sh
#!/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

```

            </td>
        </tr>
    </tbody>
</table>

[[html_data {
    "title" : "Documentación - Crear proyecto Python AnP",
    "url" : "https://anp.k3y.pw/es/py/run.html",
    "author" : "Tarsier, angelus, inoro, KyMAN",
    "since" : 20210825,
    "version" : 20210825,
    "key_words" : "anp,attach,play,attach&play,documentación,python,crear,proyecto,correr,run",
    "description" : "Creación de un proyecto Python en AnP.",
    "project" : "AnP",
    "logo" : "https://anp.k3y.pw/images/anp.png",
    "language" : "es"
}]]
